@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/conso.js
CHANGED
|
@@ -218,6 +218,11 @@ export default function calc_conso(
|
|
|
218
218
|
return acc.concat(generateur_chauffage);
|
|
219
219
|
}, []);
|
|
220
220
|
|
|
221
|
+
ecs = Array.isArray(ecs) ? ecs : [];
|
|
222
|
+
|
|
223
|
+
const conso_aux_distribution_ecs_total = ecs.reduce((acc, ecs) => {
|
|
224
|
+
return acc + (ecs.donnee_intermediaire.conso_auxiliaire_distribution_ecs || 0);
|
|
225
|
+
}, 0);
|
|
221
226
|
const gen_ecs = ecs.reduce((acc, ecs) => {
|
|
222
227
|
const generateur_ecs = ecs.generateur_ecs_collection.generateur_ecs;
|
|
223
228
|
if (prorataECS === 1) {
|
|
@@ -243,7 +248,8 @@ export default function calc_conso(
|
|
|
243
248
|
'conso',
|
|
244
249
|
null,
|
|
245
250
|
prorataECS,
|
|
246
|
-
prorataChauffage
|
|
251
|
+
prorataChauffage,
|
|
252
|
+
conso_aux_distribution_ecs_total
|
|
247
253
|
),
|
|
248
254
|
ep_conso: calc_conso_pond(
|
|
249
255
|
Sh,
|
|
@@ -255,7 +261,8 @@ export default function calc_conso(
|
|
|
255
261
|
'ep_conso',
|
|
256
262
|
coeffEp,
|
|
257
263
|
prorataECS,
|
|
258
|
-
prorataChauffage
|
|
264
|
+
prorataChauffage,
|
|
265
|
+
conso_aux_distribution_ecs_total
|
|
259
266
|
),
|
|
260
267
|
emission_ges: calc_conso_pond(
|
|
261
268
|
Sh,
|
|
@@ -267,7 +274,8 @@ export default function calc_conso(
|
|
|
267
274
|
'emission_ges',
|
|
268
275
|
coef_ges,
|
|
269
276
|
prorataECS,
|
|
270
|
-
prorataChauffage
|
|
277
|
+
prorataChauffage,
|
|
278
|
+
conso_aux_distribution_ecs_total
|
|
271
279
|
),
|
|
272
280
|
cout: calc_conso_pond(
|
|
273
281
|
Sh,
|
|
@@ -279,7 +287,8 @@ export default function calc_conso(
|
|
|
279
287
|
'cout',
|
|
280
288
|
coef_cout,
|
|
281
289
|
prorataECS,
|
|
282
|
-
prorataChauffage
|
|
290
|
+
prorataChauffage,
|
|
291
|
+
conso_aux_distribution_ecs_total
|
|
283
292
|
)
|
|
284
293
|
};
|
|
285
294
|
ret.ep_conso.classe_bilan_dpe = classe_bilan_dpe(
|
|
@@ -464,7 +473,8 @@ function calc_conso_pond(
|
|
|
464
473
|
prefix,
|
|
465
474
|
coef,
|
|
466
475
|
prorataECS,
|
|
467
|
-
prorataChauffage
|
|
476
|
+
prorataChauffage,
|
|
477
|
+
conso_aux_distribution_ecs_total
|
|
468
478
|
) {
|
|
469
479
|
const ret = {};
|
|
470
480
|
ret.auxiliaire_ventilation = vt_list.reduce((acc, vt) => {
|
|
@@ -528,7 +538,11 @@ function calc_conso_pond(
|
|
|
528
538
|
return acc + getConso(coef, 'électricité auxiliaire', conso);
|
|
529
539
|
}, 0);
|
|
530
540
|
|
|
531
|
-
ret.auxiliaire_distribution_ecs =
|
|
541
|
+
ret.auxiliaire_distribution_ecs = getConso(
|
|
542
|
+
coef,
|
|
543
|
+
'électricité auxiliaire',
|
|
544
|
+
conso_aux_distribution_ecs_total || 0
|
|
545
|
+
);
|
|
532
546
|
|
|
533
547
|
ret.ecs = getEcsConso(gen_ecs, 'conso_ecs', coef, prorataECS, prefix);
|
|
534
548
|
|
package/conso.spec.js
CHANGED
|
@@ -38,6 +38,7 @@ vi.mock('./tv.js', () => ({
|
|
|
38
38
|
}));
|
|
39
39
|
|
|
40
40
|
vi.mock('./utils.js', () => ({
|
|
41
|
+
set_bug_for_bug_compat: vi.fn(),
|
|
41
42
|
tv: vi.fn((table, matcher) => {
|
|
42
43
|
// Réseau de chaleur "R1" connu, "R2" inconnu
|
|
43
44
|
if (matcher?.identifiant_reseau === 'R1') return { contenu_co2_acv: 0.15 };
|
|
@@ -188,6 +189,7 @@ function genEcs(energieId, di, deExtra = {}) {
|
|
|
188
189
|
function installEcs(deExtra, gens) {
|
|
189
190
|
return {
|
|
190
191
|
donnee_entree: { ...deExtra },
|
|
192
|
+
donnee_intermediaire: {},
|
|
191
193
|
generateur_ecs_collection: { generateur_ecs: gens }
|
|
192
194
|
};
|
|
193
195
|
}
|
|
@@ -434,6 +436,25 @@ describe('calc_conso - agrégation des consommations', () => {
|
|
|
434
436
|
expect(res.ep_conso.ep_conso_ecs).toBeCloseTo(190, 9);
|
|
435
437
|
});
|
|
436
438
|
|
|
439
|
+
test.each([
|
|
440
|
+
['absente', undefined],
|
|
441
|
+
['nulle', null],
|
|
442
|
+
['non tabulaire', { installation_ecs: [] }]
|
|
443
|
+
])('collection ECS %s : traitée comme une liste vide', (_libelle, ecs) => {
|
|
444
|
+
const chFixture = () => [
|
|
445
|
+
installCh({ cle_repartition_ch: 1 }, [
|
|
446
|
+
genCh('1', { conso_ch: 1000, conso_ch_depensier: 1200 })
|
|
447
|
+
])
|
|
448
|
+
];
|
|
449
|
+
|
|
450
|
+
const res = calc_conso(100, 1, 1, [], chFixture(), ecs, [], 1, 1, DATE_DPE, coef_ep);
|
|
451
|
+
|
|
452
|
+
// Identique à un appel avec une collection ECS vide : aucune conso ni auxiliaire d'ECS
|
|
453
|
+
expect(res).toEqual(calc_conso(100, 1, 1, [], chFixture(), [], [], 1, 1, DATE_DPE, coef_ep));
|
|
454
|
+
expect(res.ef_conso.conso_ecs).toBe(0);
|
|
455
|
+
expect(res.ef_conso.conso_auxiliaire_distribution_ecs).toBe(0);
|
|
456
|
+
});
|
|
457
|
+
|
|
437
458
|
test('ventilation et froid : auxiliaires et froid agrégés par énergie', () => {
|
|
438
459
|
const vt = [
|
|
439
460
|
{
|
package/engine.js
CHANGED
|
@@ -3,6 +3,7 @@ import calc_deperdition from './3_deperdition.js';
|
|
|
3
3
|
import calc_apport_et_besoin from './apport_et_besoin.js';
|
|
4
4
|
import calc_clim from './10_clim.js';
|
|
5
5
|
import calc_ecs from './11_ecs.js';
|
|
6
|
+
import { conso_aux_distribution_ecs } from './15_conso_aux.js';
|
|
6
7
|
import calc_besoin_ch from './9_besoin_ch.js';
|
|
7
8
|
import calc_chauffage, { tauxChargeForGenerator } from './9_chauffage.js';
|
|
8
9
|
import calc_confort_ete from './2021_04_13_confort_ete.js';
|
|
@@ -22,6 +23,7 @@ import {
|
|
|
22
23
|
collectionCanBeEmpty,
|
|
23
24
|
containsAnySubstring,
|
|
24
25
|
isEffetJoule,
|
|
26
|
+
set_bug_for_bug_compat,
|
|
25
27
|
use_enum_as_string,
|
|
26
28
|
useEnumAsString,
|
|
27
29
|
xmlParser
|
|
@@ -31,7 +33,7 @@ import getFicheTechnique from './ficheTechnique.js';
|
|
|
31
33
|
import { ProductionENR } from './16.2_production_enr.js';
|
|
32
34
|
import DpeSanitizerService from './dpe-sanitizer.service.js';
|
|
33
35
|
|
|
34
|
-
const LIB_VERSION = '1.
|
|
36
|
+
const LIB_VERSION = '1.7.1';
|
|
35
37
|
|
|
36
38
|
const dpeSanitizerService = new DpeSanitizerService();
|
|
37
39
|
|
|
@@ -70,6 +72,7 @@ export function calcul_3cl_xml(dpeXmlContent, options) {
|
|
|
70
72
|
* @return {FullDpe}
|
|
71
73
|
*/
|
|
72
74
|
export function calcul_3cl(inputDpe, options) {
|
|
75
|
+
set_bug_for_bug_compat();
|
|
73
76
|
if (!options) options = { sanitize: true };
|
|
74
77
|
let dpe;
|
|
75
78
|
if (options.sanitize) {
|
|
@@ -90,6 +93,7 @@ export function calcul_3cl(inputDpe, options) {
|
|
|
90
93
|
|
|
91
94
|
const cg = logement.caracteristique_generale;
|
|
92
95
|
const map_id = cg.enum_methode_application_dpe_log_id;
|
|
96
|
+
const dpeGenereImmeuble = ['10', '11', '12', '13', '33', '34', '38', '39', '40'].includes(map_id);
|
|
93
97
|
const th = calc_th(map_id);
|
|
94
98
|
|
|
95
99
|
if (logement.enveloppe === undefined) {
|
|
@@ -435,6 +439,20 @@ export function calcul_3cl(inputDpe, options) {
|
|
|
435
439
|
dpe.logement.caracteristique_generale.nombre_appartement,
|
|
436
440
|
isImmeubleSystemEcsIndividuels
|
|
437
441
|
);
|
|
442
|
+
|
|
443
|
+
if (!dpeGenereImmeuble) {
|
|
444
|
+
conso_aux_distribution_ecs(
|
|
445
|
+
ecs,
|
|
446
|
+
ecs.donnee_entree,
|
|
447
|
+
ecs.donnee_intermediaire,
|
|
448
|
+
Sh,
|
|
449
|
+
cg.surface_habitable_immeuble,
|
|
450
|
+
ca_id,
|
|
451
|
+
zc_id,
|
|
452
|
+
apport_et_besoin.nadeq,
|
|
453
|
+
dpe.logement.caracteristique_generale.nombre_niveau_immeuble
|
|
454
|
+
);
|
|
455
|
+
}
|
|
438
456
|
});
|
|
439
457
|
|
|
440
458
|
/**
|
package/engine.spec.js
CHANGED
|
@@ -20,6 +20,7 @@ let bugForBugCompat = false;
|
|
|
20
20
|
let useEnumAsStringFlag = false;
|
|
21
21
|
|
|
22
22
|
vi.mock('./utils.js', () => ({
|
|
23
|
+
set_bug_for_bug_compat: vi.fn(),
|
|
23
24
|
add_references: vi.fn(),
|
|
24
25
|
get bug_for_bug_compat() {
|
|
25
26
|
return bugForBugCompat;
|
|
@@ -65,6 +66,7 @@ vi.mock('./10_clim.js', () => ({ default: vi.fn() }));
|
|
|
65
66
|
vi.mock('./11_ecs.js', () => ({ default: vi.fn() }));
|
|
66
67
|
vi.mock('./9_besoin_ch.js', () => ({ default: vi.fn() }));
|
|
67
68
|
vi.mock('./9_chauffage.js', () => ({ default: vi.fn(), tauxChargeForGenerator: vi.fn() }));
|
|
69
|
+
vi.mock('./15_conso_aux.js', () => ({ conso_aux_distribution_ecs: vi.fn() }));
|
|
68
70
|
vi.mock('./2021_04_13_confort_ete.js', () => ({ default: vi.fn() }));
|
|
69
71
|
vi.mock('./2021_04_13_qualite_isolation.js', () => ({ default: vi.fn() }));
|
|
70
72
|
vi.mock('./ficheTechnique.js', () => ({ default: vi.fn() }));
|
|
@@ -102,6 +104,7 @@ const calc_clim = (await import('./10_clim.js')).default;
|
|
|
102
104
|
const calc_ecs = (await import('./11_ecs.js')).default;
|
|
103
105
|
const calc_besoin_ch = (await import('./9_besoin_ch.js')).default;
|
|
104
106
|
const { default: calc_chauffage, tauxChargeForGenerator } = await import('./9_chauffage.js');
|
|
107
|
+
const { conso_aux_distribution_ecs } = await import('./15_conso_aux.js');
|
|
105
108
|
const calc_confort_ete = (await import('./2021_04_13_confort_ete.js')).default;
|
|
106
109
|
const calc_qualite_isolation = (await import('./2021_04_13_qualite_isolation.js')).default;
|
|
107
110
|
const getFicheTechnique = (await import('./ficheTechnique.js')).default;
|
|
@@ -172,6 +175,7 @@ function makeDpe() {
|
|
|
172
175
|
surface_habitable_logement: 80,
|
|
173
176
|
surface_habitable_immeuble: 200,
|
|
174
177
|
nombre_appartement: 4,
|
|
178
|
+
nombre_niveau_immeuble: 3,
|
|
175
179
|
hsp: 2.5,
|
|
176
180
|
annee_construction: 1990
|
|
177
181
|
},
|
|
@@ -192,6 +196,7 @@ function makeDpe() {
|
|
|
192
196
|
installation_ecs: [
|
|
193
197
|
{
|
|
194
198
|
donnee_entree: { enum_type_installation_id: '1' },
|
|
199
|
+
donnee_intermediaire: {},
|
|
195
200
|
generateur_ecs_collection: { generateur_ecs: [] }
|
|
196
201
|
}
|
|
197
202
|
]
|
|
@@ -455,6 +460,22 @@ describe('calcul_3cl - run intégral (maison)', () => {
|
|
|
455
460
|
expect(calc_ecs.mock.calls[0][2]).toBe(100);
|
|
456
461
|
expect(calc_ecs.mock.calls[0][11]).toBe(false);
|
|
457
462
|
|
|
463
|
+
// Auxiliaires de distribution ECS calculés pour l'installation (maison => map hors
|
|
464
|
+
// liste des DPE générés à partir des données d'immeuble).
|
|
465
|
+
const ecs = dpe.logement.installation_ecs_collection.installation_ecs[0];
|
|
466
|
+
expect(conso_aux_distribution_ecs).toHaveBeenCalledTimes(1);
|
|
467
|
+
expect(conso_aux_distribution_ecs).toHaveBeenCalledWith(
|
|
468
|
+
ecs,
|
|
469
|
+
ecs.donnee_entree,
|
|
470
|
+
ecs.donnee_intermediaire,
|
|
471
|
+
80, // Sh (maison)
|
|
472
|
+
200, // surface_habitable_immeuble
|
|
473
|
+
'ca1',
|
|
474
|
+
'zc1',
|
|
475
|
+
2, // nadeq
|
|
476
|
+
3 // nombre_niveau_immeuble
|
|
477
|
+
);
|
|
478
|
+
|
|
458
479
|
// Climatisation présente : calc_clim appelé.
|
|
459
480
|
expect(calc_clim).toHaveBeenCalledTimes(1);
|
|
460
481
|
});
|
|
@@ -484,6 +505,7 @@ describe('calcul_3cl - run intégral (maison)', () => {
|
|
|
484
505
|
expect(calc_apport_et_besoin.mock.calls[0][5]).toBe(1);
|
|
485
506
|
// Pas d'ECS ni de clim à traiter.
|
|
486
507
|
expect(calc_ecs).not.toHaveBeenCalled();
|
|
508
|
+
expect(conso_aux_distribution_ecs).not.toHaveBeenCalled();
|
|
487
509
|
expect(calc_clim).not.toHaveBeenCalled();
|
|
488
510
|
});
|
|
489
511
|
});
|
|
@@ -538,6 +560,9 @@ describe('calcul_3cl - surfaces immeuble / appartement et prorata', () => {
|
|
|
538
560
|
// isImmeubleSystemEcsIndividuels = true, besoin non divisé.
|
|
539
561
|
expect(calc_ecs.mock.calls[0][11]).toBe(true);
|
|
540
562
|
expect(calc_ecs.mock.calls[0][2]).toBe(100);
|
|
563
|
+
// Auxiliaires ECS calculés par installation, avec Sh = surface immeuble.
|
|
564
|
+
expect(conso_aux_distribution_ecs).toHaveBeenCalledTimes(2);
|
|
565
|
+
expect(conso_aux_distribution_ecs.mock.calls[0][3]).toBe(200);
|
|
541
566
|
});
|
|
542
567
|
|
|
543
568
|
test('immeuble : systèmes ECS non tous individuels => besoin divisé par deux', () => {
|
|
@@ -593,6 +618,77 @@ describe('calcul_3cl - surfaces immeuble / appartement et prorata', () => {
|
|
|
593
618
|
expect(calc_conso.mock.calls[0][0]).toBe(80);
|
|
594
619
|
expect(calc_conso.mock.calls[0][7]).toBeCloseTo(0.4, 9); // prorataECS
|
|
595
620
|
expect(calc_conso.mock.calls[0][8]).toBeCloseTo(0.4, 9); // prorataChauffage
|
|
621
|
+
// Auxiliaires ECS : Sh = surface logement, ramenée à l'immeuble dans le calcul.
|
|
622
|
+
expect(conso_aux_distribution_ecs.mock.calls[0][3]).toBe(80);
|
|
623
|
+
expect(conso_aux_distribution_ecs.mock.calls[0][4]).toBe(200);
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
describe("calcul_3cl - auxiliaires de distribution d'ECS", () => {
|
|
628
|
+
// Méthodes d'application « appartement généré à partir des données DPE immeuble » :
|
|
629
|
+
// les auxiliaires de distribution d'ECS ne sont pas calculés pour ces DPE.
|
|
630
|
+
const MAP_IDS_GENERES_IMMEUBLE = ['10', '11', '12', '13', '33', '34', '38', '39', '40'];
|
|
631
|
+
|
|
632
|
+
test.each(MAP_IDS_GENERES_IMMEUBLE)(
|
|
633
|
+
"DPE appartement généré à partir des données d'immeuble (map %s) : auxiliaires non calculés",
|
|
634
|
+
(mapId) => {
|
|
635
|
+
enums.methode_application_dpe_log = {
|
|
636
|
+
[mapId]: 'dpe appartement généré à partir des données dpe immeuble chauffage collectif'
|
|
637
|
+
};
|
|
638
|
+
const dpe = makeDpe();
|
|
639
|
+
dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = mapId;
|
|
640
|
+
|
|
641
|
+
calcul_3cl(dpe, { sanitize: false });
|
|
642
|
+
|
|
643
|
+
// L'installation est bien traitée par ailleurs, seul le calcul des auxiliaires est ignoré.
|
|
644
|
+
expect(calc_ecs).toHaveBeenCalledTimes(1);
|
|
645
|
+
expect(conso_aux_distribution_ecs).not.toHaveBeenCalled();
|
|
646
|
+
}
|
|
647
|
+
);
|
|
648
|
+
|
|
649
|
+
test('appartement non généré depuis un immeuble (map 15) : auxiliaires calculés', () => {
|
|
650
|
+
enums.methode_application_dpe_log = { 15: 'dpe appartement collectif' };
|
|
651
|
+
const dpe = makeDpe();
|
|
652
|
+
dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = '15';
|
|
653
|
+
|
|
654
|
+
calcul_3cl(dpe, { sanitize: false });
|
|
655
|
+
|
|
656
|
+
expect(conso_aux_distribution_ecs).toHaveBeenCalledTimes(1);
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
test('une installation ECS par appel : chaque installation est traitée', () => {
|
|
660
|
+
const dpe = makeDpe();
|
|
661
|
+
const installations = [
|
|
662
|
+
{
|
|
663
|
+
donnee_entree: { enum_type_installation_id: '1' },
|
|
664
|
+
donnee_intermediaire: { tag: 'ecs1' },
|
|
665
|
+
generateur_ecs_collection: { generateur_ecs: [] }
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
donnee_entree: { enum_type_installation_id: '2' },
|
|
669
|
+
donnee_intermediaire: { tag: 'ecs2' },
|
|
670
|
+
generateur_ecs_collection: { generateur_ecs: [] }
|
|
671
|
+
}
|
|
672
|
+
];
|
|
673
|
+
dpe.logement.installation_ecs_collection.installation_ecs = installations;
|
|
674
|
+
|
|
675
|
+
calcul_3cl(dpe, { sanitize: false });
|
|
676
|
+
|
|
677
|
+
expect(conso_aux_distribution_ecs).toHaveBeenCalledTimes(2);
|
|
678
|
+
installations.forEach((ecs, i) => {
|
|
679
|
+
expect(conso_aux_distribution_ecs.mock.calls[i][0]).toBe(ecs);
|
|
680
|
+
expect(conso_aux_distribution_ecs.mock.calls[i][1]).toBe(ecs.donnee_entree);
|
|
681
|
+
expect(conso_aux_distribution_ecs.mock.calls[i][2]).toBe(ecs.donnee_intermediaire);
|
|
682
|
+
});
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
test("nombre de niveaux de l'immeuble absent : transmis tel quel", () => {
|
|
686
|
+
const dpe = makeDpe();
|
|
687
|
+
dpe.logement.caracteristique_generale.nombre_niveau_immeuble = undefined;
|
|
688
|
+
|
|
689
|
+
calcul_3cl(dpe, { sanitize: false });
|
|
690
|
+
|
|
691
|
+
expect(conso_aux_distribution_ecs.mock.calls[0][8]).toBeUndefined();
|
|
596
692
|
});
|
|
597
693
|
});
|
|
598
694
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open3cl/engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "Open Source 3CL-DPE engine",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"directories": {
|
|
@@ -13,13 +13,11 @@
|
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
15
|
"http-server": "http-server",
|
|
16
|
-
"test": "vitest run",
|
|
16
|
+
"test": "vitest run src",
|
|
17
17
|
"test:unit": "vitest run src",
|
|
18
18
|
"test:unit:ci": "vitest run src --coverage",
|
|
19
|
-
"test:int": "vitest run test",
|
|
20
|
-
"test:int:ci": "vitest run test --coverage",
|
|
21
19
|
"test:corpus": "node test/corpus/run_all_corpus_checks.js",
|
|
22
|
-
"test:corpus:all": "node test/corpus/run_all_corpus_checks.js",
|
|
20
|
+
"test:corpus:all": "node test/corpus/run_all_corpus_checks.js && npm run reports:readme",
|
|
23
21
|
"test:corpus:all+database": "npm run test:corpus:all && node test/corpus/corpus_database.js",
|
|
24
22
|
"qa:lint": "eslint .",
|
|
25
23
|
"qa:lint:fix": "npm run qa:lint -- --fix",
|
|
@@ -30,7 +28,8 @@
|
|
|
30
28
|
"prepare": "husky install",
|
|
31
29
|
"assets:sync": "node scripts/synchronize_assets.js",
|
|
32
30
|
"version:update": "node scripts/update_version.js",
|
|
33
|
-
"reports:preview": "npm run http-server dist/reports/corpus -o"
|
|
31
|
+
"reports:preview": "npm run http-server dist/reports/corpus -o",
|
|
32
|
+
"reports:readme": "node scripts/generate_corpus_readme.js"
|
|
34
33
|
},
|
|
35
34
|
"repository": {
|
|
36
35
|
"type": "git",
|
|
@@ -42,11 +41,12 @@
|
|
|
42
41
|
],
|
|
43
42
|
"dependencies": {
|
|
44
43
|
"dioma": "^0.4.6",
|
|
45
|
-
"fast-xml-parser": "^
|
|
44
|
+
"fast-xml-parser": "^5.11.1",
|
|
46
45
|
"http-server": "^14.1.1",
|
|
47
|
-
"lodash-es": "4.
|
|
48
|
-
"mathjs": "^15.
|
|
49
|
-
"winston": "3.
|
|
46
|
+
"lodash-es": "^4.18.1",
|
|
47
|
+
"mathjs": "^15.2.0",
|
|
48
|
+
"winston": "^3.19.0",
|
|
49
|
+
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@aws-sdk/client-s3": "^3.1013.0",
|
|
@@ -59,11 +59,10 @@
|
|
|
59
59
|
"@semantic-release/git": "^10.0.1",
|
|
60
60
|
"@semantic-release/github": "^12.0.2",
|
|
61
61
|
"@types/node": "^20.12.4",
|
|
62
|
-
"@vitest/coverage-v8": "^3.
|
|
62
|
+
"@vitest/coverage-v8": "^3.2.7",
|
|
63
63
|
"ansi-colors": "^4.1.3",
|
|
64
64
|
"cli-progress": "^3.12.0",
|
|
65
65
|
"deep-object-diff": "^1.1.9",
|
|
66
|
-
"duckdb": "^1.3.2",
|
|
67
66
|
"eslint": "^8.57.0",
|
|
68
67
|
"eslint-config-prettier": "^9.1.0",
|
|
69
68
|
"eslint-config-standard": "^17.1.0",
|
|
@@ -78,11 +77,13 @@
|
|
|
78
77
|
"prettier": "^3.2.5",
|
|
79
78
|
"pretty-quick": "^4.0.0",
|
|
80
79
|
"semantic-release": "^25.0.2",
|
|
81
|
-
"vitest": "3.
|
|
82
|
-
"xlsx": "0.18.5"
|
|
80
|
+
"vitest": "3.2.7"
|
|
83
81
|
},
|
|
84
82
|
"author": "Open3Cl",
|
|
85
83
|
"license": "GPL-3.0",
|
|
84
|
+
"engines": {
|
|
85
|
+
"node": ">=24.14.1"
|
|
86
|
+
},
|
|
86
87
|
"bugs": {
|
|
87
88
|
"url": "https://github.com/Open3CL/engine/issues"
|
|
88
89
|
},
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
-
import { SurfaceSudEquivalenteService } from './surface-sud-equivalente.service.js';
|
|
3
|
-
import { BaieVitreeTvStore } from '../../../dpe/infrastructure/enveloppe/baieVitreeTv.store.js';
|
|
4
|
-
import { ApportEtBesoinService } from './apport-et-besoin.service.js';
|
|
5
|
-
import { BesoinEcsService } from './ecs/besoin-ecs.service.js';
|
|
6
|
-
import { BesoinFroidService } from './froid/besoin-froid.service.js';
|
|
7
|
-
import { ApportGratuitService } from './apport_gratuit/apport-gratuit.service.js';
|
|
8
|
-
import { PerteEcsRecupService } from './ecs/perte-ecs-recup.service.js';
|
|
9
|
-
import { InstallationEcsService } from '../ecs/installation-ecs.service.js';
|
|
10
|
-
import { PerteChRecupService } from './ch/perte-ch-recup.service.js';
|
|
11
|
-
import { BesoinChService } from './ch/besoin-ch.service.js';
|
|
12
|
-
import corpus from '../../../../../test/corpus-sano.json';
|
|
13
|
-
import { getAdemeFileJson } from '../../../../../test/test-helpers.js';
|
|
14
|
-
import { PRECISION_PERCENT } from '../../../../../test/constant.js';
|
|
15
|
-
import { DpeNormalizerService } from '../../../normalizer/domain/dpe-normalizer.service.js';
|
|
16
|
-
import { ContexteBuilder } from '../contexte.builder.js';
|
|
17
|
-
import { InstallationChService } from '../ch/installation-ch.service.js';
|
|
18
|
-
import { describeIntegration } from '../../../../../test/helpers/integration-test.js';
|
|
19
|
-
|
|
20
|
-
/** @type {SurfaceSudEquivalenteService} **/
|
|
21
|
-
let surfaceSudEquivalenteService;
|
|
22
|
-
|
|
23
|
-
/** @type {BesoinEcsService} **/
|
|
24
|
-
let besoinEcsService;
|
|
25
|
-
|
|
26
|
-
/** @type {BesoinFroidService} **/
|
|
27
|
-
let besoinFroidService;
|
|
28
|
-
|
|
29
|
-
/** @type {InstallationEcsService} **/
|
|
30
|
-
let installationEcsService;
|
|
31
|
-
|
|
32
|
-
/** @type {InstallationChService} **/
|
|
33
|
-
let installationChService;
|
|
34
|
-
|
|
35
|
-
/** @type {PerteEcsRecupService} **/
|
|
36
|
-
let perteEcsRecupService;
|
|
37
|
-
|
|
38
|
-
/** @type {ApportGratuitService} **/
|
|
39
|
-
let apportGratuitService;
|
|
40
|
-
|
|
41
|
-
/** @type {PerteChRecupService} **/
|
|
42
|
-
let perteChRecupService;
|
|
43
|
-
|
|
44
|
-
/** @type {BesoinChService} **/
|
|
45
|
-
let besoinChService;
|
|
46
|
-
|
|
47
|
-
/** @type {DpeNormalizerService} **/
|
|
48
|
-
let normalizerService;
|
|
49
|
-
|
|
50
|
-
/** @type {ContexteBuilder} **/
|
|
51
|
-
let contexteBuilder;
|
|
52
|
-
|
|
53
|
-
/** @type {ApportEtBesoinService} **/
|
|
54
|
-
let service;
|
|
55
|
-
|
|
56
|
-
/** @type {BaieVitreeTvStore} **/
|
|
57
|
-
let tvStore;
|
|
58
|
-
|
|
59
|
-
describe('Calcul des apports et besoin du logement', () => {
|
|
60
|
-
beforeEach(() => {
|
|
61
|
-
tvStore = new BaieVitreeTvStore();
|
|
62
|
-
surfaceSudEquivalenteService = new SurfaceSudEquivalenteService(tvStore);
|
|
63
|
-
besoinEcsService = new BesoinEcsService();
|
|
64
|
-
besoinChService = new BesoinChService();
|
|
65
|
-
besoinFroidService = new BesoinFroidService();
|
|
66
|
-
installationEcsService = new InstallationEcsService();
|
|
67
|
-
installationChService = new InstallationChService();
|
|
68
|
-
perteEcsRecupService = new PerteEcsRecupService();
|
|
69
|
-
apportGratuitService = new ApportGratuitService();
|
|
70
|
-
perteChRecupService = new PerteChRecupService();
|
|
71
|
-
service = new ApportEtBesoinService(
|
|
72
|
-
besoinEcsService,
|
|
73
|
-
besoinChService,
|
|
74
|
-
installationEcsService,
|
|
75
|
-
installationChService,
|
|
76
|
-
perteEcsRecupService,
|
|
77
|
-
besoinFroidService,
|
|
78
|
-
surfaceSudEquivalenteService,
|
|
79
|
-
perteChRecupService,
|
|
80
|
-
apportGratuitService
|
|
81
|
-
);
|
|
82
|
-
normalizerService = new DpeNormalizerService();
|
|
83
|
-
contexteBuilder = new ContexteBuilder();
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
test('Determination des apports et besoin du logement', () => {
|
|
87
|
-
vi.spyOn(surfaceSudEquivalenteService, 'execute').mockReturnValue(18.5);
|
|
88
|
-
vi.spyOn(besoinEcsService, 'execute').mockReturnValue({
|
|
89
|
-
besoin_ecs: 1526,
|
|
90
|
-
besoin_ecs_depensier: 2685.3
|
|
91
|
-
});
|
|
92
|
-
vi.spyOn(besoinChService, 'execute').mockReturnValue({
|
|
93
|
-
besoin_ch_hp: 2563,
|
|
94
|
-
besoin_ch_depensier_hp: 3258.6
|
|
95
|
-
});
|
|
96
|
-
vi.spyOn(besoinFroidService, 'execute').mockReturnValue({
|
|
97
|
-
besoin_fr: 896,
|
|
98
|
-
besoin_fr_depensier: 1025.3
|
|
99
|
-
});
|
|
100
|
-
vi.spyOn(apportGratuitService, 'apportSolaire').mockReturnValue({
|
|
101
|
-
apport_solaire_ch: 5236.9,
|
|
102
|
-
apport_solaire_fr: 145.2
|
|
103
|
-
});
|
|
104
|
-
vi.spyOn(apportGratuitService, 'apportInterne').mockReturnValue({
|
|
105
|
-
apport_interne_ch: 1236.9,
|
|
106
|
-
apport_interne_fr: 3345.2
|
|
107
|
-
});
|
|
108
|
-
vi.spyOn(installationEcsService, 'execute').mockReturnThis();
|
|
109
|
-
vi.spyOn(installationChService, 'execute').mockReturnThis();
|
|
110
|
-
vi.spyOn(perteEcsRecupService, 'execute').mockReturnValue({
|
|
111
|
-
pertes_distribution_ecs_recup: 354.2,
|
|
112
|
-
pertes_distribution_ecs_recup_depensier: 532.6,
|
|
113
|
-
pertes_stockage_ecs_recup: 25.9,
|
|
114
|
-
pertes_stockage_ecs_recup_depensier: 12.9
|
|
115
|
-
});
|
|
116
|
-
vi.spyOn(perteChRecupService, 'execute').mockReturnValue({
|
|
117
|
-
pertes_generateur_ch_recup: 102.2,
|
|
118
|
-
pertes_generateur_ch_recup_depensier: 153.4
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
/** @type {Contexte} */
|
|
122
|
-
const ctx = { zoneClimatique: { id: 1 }, nadeq: 2.5 };
|
|
123
|
-
/** @type { Logement } **/
|
|
124
|
-
const logement = { enveloppe: {} };
|
|
125
|
-
expect(service.execute(ctx, logement)).toStrictEqual({
|
|
126
|
-
surface_sud_equivalente: 18.5,
|
|
127
|
-
besoin_ecs: 1526,
|
|
128
|
-
besoin_ecs_depensier: 2685.3,
|
|
129
|
-
besoin_ch: 2080.7000000000003,
|
|
130
|
-
besoin_ch_depensier: 2559.7,
|
|
131
|
-
besoin_fr: 896,
|
|
132
|
-
besoin_fr_depensier: 1025.3,
|
|
133
|
-
apport_solaire_ch: 5236.9,
|
|
134
|
-
apport_solaire_fr: 145.2,
|
|
135
|
-
apport_interne_ch: 1236.9,
|
|
136
|
-
apport_interne_fr: 3345.2,
|
|
137
|
-
nadeq: 2.5,
|
|
138
|
-
v40_ecs_journalier: 140,
|
|
139
|
-
v40_ecs_journalier_depensier: 197.5,
|
|
140
|
-
pertes_distribution_ecs_recup: 354.2,
|
|
141
|
-
pertes_distribution_ecs_recup_depensier: 532.6,
|
|
142
|
-
pertes_generateur_ch_recup: 102.2,
|
|
143
|
-
pertes_generateur_ch_recup_depensier: 153.4,
|
|
144
|
-
pertes_stockage_ecs_recup: 25.9,
|
|
145
|
-
pertes_stockage_ecs_recup_depensier: 12.9
|
|
146
|
-
});
|
|
147
|
-
expect(surfaceSudEquivalenteService.execute).toHaveBeenCalledWith(ctx, logement.enveloppe);
|
|
148
|
-
expect(besoinEcsService.execute).toHaveBeenCalledWith(ctx);
|
|
149
|
-
expect(besoinFroidService.execute).toHaveBeenCalledWith(ctx, logement);
|
|
150
|
-
expect(apportGratuitService.apportSolaire).toHaveBeenCalledWith(ctx, logement);
|
|
151
|
-
expect(apportGratuitService.apportInterne).toHaveBeenCalledWith(ctx, logement);
|
|
152
|
-
expect(perteEcsRecupService.execute).toHaveBeenCalledWith(ctx, logement);
|
|
153
|
-
expect(perteChRecupService.execute).toHaveBeenCalledWith(ctx, logement);
|
|
154
|
-
expect(installationEcsService.execute).toHaveBeenCalledWith(ctx, logement, {
|
|
155
|
-
besoin_ecs: 1526,
|
|
156
|
-
besoin_ecs_depensier: 2685.3
|
|
157
|
-
});
|
|
158
|
-
expect(installationChService.execute).toHaveBeenCalledWith(ctx, logement);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
describeIntegration("Test d'intégration pour les besoins en chauffage", () => {
|
|
162
|
-
test.each(corpus)(
|
|
163
|
-
'Vérification de la DI besoin_ch des besoins en chauffage pour dpe %s',
|
|
164
|
-
(ademeId) => {
|
|
165
|
-
/**
|
|
166
|
-
* @type {Dpe}
|
|
167
|
-
*/
|
|
168
|
-
let dpeRequest = getAdemeFileJson(ademeId);
|
|
169
|
-
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
170
|
-
|
|
171
|
-
dpeRequest.logement.donnees_de_calcul = {
|
|
172
|
-
apportsInterneDepensier: [],
|
|
173
|
-
apportsInterneCh: [],
|
|
174
|
-
apportsSolaire: [],
|
|
175
|
-
besoinChauffageHP: [],
|
|
176
|
-
besoinChauffageDepensierHP: []
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
/** @type {Contexte} */
|
|
180
|
-
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
181
|
-
const apportEtBesoin = service.execute(ctx, dpeRequest.logement);
|
|
182
|
-
|
|
183
|
-
expect(
|
|
184
|
-
Math.abs(
|
|
185
|
-
apportEtBesoin.besoin_ch - dpeRequest.logement.sortie.apport_et_besoin.besoin_ch
|
|
186
|
-
) / (dpeRequest.logement.sortie.apport_et_besoin.besoin_ch || 1)
|
|
187
|
-
).toBeLessThan(PRECISION_PERCENT);
|
|
188
|
-
}
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
test.each(corpus)(
|
|
192
|
-
'Vérification de la DI besoin_ch_depensier des besoins en chauffage pour dpe %s',
|
|
193
|
-
(ademeId) => {
|
|
194
|
-
/**
|
|
195
|
-
* @type {Dpe}
|
|
196
|
-
*/
|
|
197
|
-
let dpeRequest = getAdemeFileJson(ademeId);
|
|
198
|
-
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
199
|
-
|
|
200
|
-
dpeRequest.logement.donnees_de_calcul = {
|
|
201
|
-
apportsInterneDepensier: [],
|
|
202
|
-
apportsInterneCh: [],
|
|
203
|
-
apportsSolaire: [],
|
|
204
|
-
besoinChauffageHP: [],
|
|
205
|
-
besoinChauffageDepensierHP: []
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
/** @type {Contexte} */
|
|
209
|
-
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
210
|
-
|
|
211
|
-
const apportEtBesoin = service.execute(ctx, dpeRequest.logement);
|
|
212
|
-
|
|
213
|
-
expect(
|
|
214
|
-
Math.abs(
|
|
215
|
-
apportEtBesoin.besoin_ch_depensier -
|
|
216
|
-
dpeRequest.logement.sortie.apport_et_besoin.besoin_ch_depensier
|
|
217
|
-
) / (dpeRequest.logement.sortie.apport_et_besoin.besoin_ch_depensier || 1)
|
|
218
|
-
).toBeLessThan(PRECISION_PERCENT);
|
|
219
|
-
}
|
|
220
|
-
);
|
|
221
|
-
});
|
|
222
|
-
});
|