@open3cl/engine 1.6.1 → 1.6.2
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 +122 -0
- package/10_clim.spec.js +116 -0
- package/11_besoin_ecs.spec.js +69 -0
- package/11_ecs.spec.js +282 -0
- package/11_nadeq.spec.js +37 -0
- package/12.4_pac.spec.js +131 -0
- package/13.2_generateur_combustion.js +2 -0
- package/13.2_generateur_combustion.spec.js +537 -0
- package/13.2_generateur_combustion_bouilleur.js +4 -1
- package/13.2_generateur_combustion_bouilleur.spec.js +74 -0
- package/13.2_generateur_combustion_ch.spec.js +323 -0
- package/13.2_generateur_combustion_chaudiere.spec.js +85 -0
- package/13.2_generateur_pac.spec.js +64 -0
- package/13_rendement_distribution_ecs.spec.js +38 -0
- package/14_generateur_ecs.js +4 -4
- package/14_generateur_ecs.spec.js +745 -0
- package/15_conso_aux.spec.js +225 -0
- package/16.2_production_enr.spec.js +188 -0
- package/16_conso_eclairage.spec.js +62 -0
- package/2021_04_13_confort_ete.spec.js +159 -0
- package/2021_04_13_qualite_isolation.js +1 -1
- package/2021_04_13_qualite_isolation.spec.js +286 -0
- package/3.1_b.js +1 -1
- package/3.1_b.spec.js +367 -0
- package/3.2.1_mur.spec.js +812 -39
- package/3.2.2_plancher_bas.spec.js +643 -78
- package/3.2.3_plancher_haut.spec.js +452 -0
- package/3.3.1.4_porte.spec.js +114 -0
- package/3.3_baie_vitree.spec.js +449 -295
- package/3.4_pont_thermique.spec.js +890 -0
- package/3_deperdition.spec.js +397 -0
- package/4_ventilation.js +1 -1
- package/4_ventilation.spec.js +406 -0
- package/5_conso_ventilation.spec.js +186 -0
- package/6.2_surface_sud_equivalente.spec.js +138 -0
- package/8_intermittence.spec.js +33 -0
- package/9_besoin_ch.js +2 -2
- package/9_besoin_ch.spec.js +381 -0
- package/9_chauffage.js +4 -0
- package/9_chauffage.spec.js +478 -92
- package/9_conso_ch.spec.js +502 -248
- package/9_emetteur_ch.spec.js +339 -0
- package/9_generateur_ch.spec.js +467 -81
- package/apport_et_besoin.spec.js +126 -0
- package/conso.js +1 -1
- package/conso.spec.js +471 -82
- package/core/assets/domain/add-additionnal-ue-values-tables.spec.js +53 -0
- package/core/assets/domain/synchronize-solicitations-tables.spec.js +25 -0
- package/core/assets/domain/synchronize-valeur-tables.spec.js +48 -0
- package/core/conf/infrastructure/application.config.spec.js +35 -0
- package/core/file/infrastructure/adapter/csv-parser.store.spec.js +31 -13
- package/core/file/infrastructure/adapter/file.store.spec.js +148 -12
- package/core/tv/infrastructure/assets/additional-ue-values.spec.js +36 -0
- package/core/util/infrastructure/object-util.spec.js +20 -0
- package/core/util/logger/log-service.js +16 -7
- package/core/util/logger/log-service.spec.js +101 -0
- package/dpe-sanitizer.service.spec.js +138 -0
- package/engine.js +4 -1
- package/engine.spec.js +854 -0
- package/enums.spec.js +46 -0
- package/features/dpe/domain/models/type-generateur.model.js +1 -2
- package/features/dpe/domain/models/type-generateur.model.spec.js +25 -0
- package/features/dpe/domain/models/type-habitation.model.spec.js +41 -0
- package/features/dpe/domain/models/type-stockage.model.spec.js +18 -0
- package/features/dpe/domain/models/type-ventilation.model.spec.js +19 -0
- package/features/dpe/infrastructure/ch/chTv.store.spec.js +4 -4
- package/features/dpe/infrastructure/enveloppe/baieVitreeTv.store.js +14 -2
- package/features/dpe/infrastructure/enveloppe/baieVitreeTv.store.spec.js +16 -0
- package/features/dpe/infrastructure/tv.store.js +28 -9
- package/features/dpe/infrastructure/tv.store.spec.js +44 -0
- package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.spec.js +2 -1
- package/features/engine/domain/apport_et_besoin/ch/besoin-ch.service.spec.js +18 -0
- package/features/engine/domain/apport_et_besoin/ch/perte-ch-recup.service.spec.js +33 -1
- package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.spec.js +21 -1
- package/features/engine/domain/apport_et_besoin/ecs/perte-ecs-recup.service.spec.js +41 -1
- package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.spec.js +44 -1
- package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.spec.js +2 -1
- package/features/engine/domain/ch/generateur-ch.service.js +2 -0
- package/features/engine/domain/ch/generateur-ch.service.spec.js +117 -2
- package/features/engine/domain/ch/installation-ch.service.spec.js +14 -0
- package/features/engine/domain/conso/froid/conso-froid.service.spec.js +82 -1
- package/features/engine/domain/constants.spec.js +14 -0
- package/features/engine/domain/contexte.builder.spec.js +21 -0
- package/features/engine/domain/ecs/generateur-ecs.service.spec.js +11 -0
- package/features/engine/domain/ecs/installation-ecs.service.spec.js +55 -2
- package/features/engine/domain/engine.service.spec.js +227 -4
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.spec.js +124 -1
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.spec.js +270 -2
- package/features/engine/domain/enveloppe/deperdition.service.spec.js +141 -0
- package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.spec.js +2 -1
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +117 -1
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +134 -1
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +126 -1
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +18 -1
- package/features/engine/domain/enveloppe/porte/deperdition-porte.service.spec.js +2 -1
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +67 -1
- package/features/normalizer/domain/dpe-normalizer.service.js +1 -1
- package/features/normalizer/domain/dpe-normalizer.service.spec.js +53 -2
- package/ficheTechnique.spec.js +26 -0
- package/index.spec.js +54 -0
- package/package.json +5 -2
- package/preprocessor/index.js +20 -0
- package/preprocessor/index.spec.js +15 -0
- package/tv.spec.js +38 -0
- package/utils.js +43 -1
- package/utils.spec.js +518 -2
- package/output.js +0 -1
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Dépendances mockées pour isoler l'orchestrateur `calc_deperdition` :
|
|
5
|
+
* - `enums` : mapping minimal des types d'adjacence (utilisé par le calcul de Sdep) ;
|
|
6
|
+
* - tous les modules de calcul par paroi (`calc_mur`, `calc_pb`, `calc_ph`, `calc_bv`,
|
|
7
|
+
* `calc_porte`, `calc_pont_thermique`, `calc_ventilation`) : espions no-op, les données
|
|
8
|
+
* intermédiaires sont donc pré-remplies dans les fixtures.
|
|
9
|
+
*/
|
|
10
|
+
vi.mock('./enums.js', () => ({
|
|
11
|
+
default: {
|
|
12
|
+
type_adjacence: {
|
|
13
|
+
1: 'extérieur',
|
|
14
|
+
2: "local non déperditif (local à usage d'habitation chauffé)"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
vi.mock('./3.2.1_mur.js', () => ({ default: vi.fn() }));
|
|
20
|
+
vi.mock('./3.2.2_plancher_bas.js', () => ({ default: vi.fn() }));
|
|
21
|
+
vi.mock('./3.2.3_plancher_haut.js', () => ({ default: vi.fn() }));
|
|
22
|
+
vi.mock('./3.3_baie_vitree.js', () => ({ default: vi.fn() }));
|
|
23
|
+
vi.mock('./3.3.1.4_porte.js', () => ({ default: vi.fn() }));
|
|
24
|
+
vi.mock('./3.4_pont_thermique.js', () => ({ default: vi.fn() }));
|
|
25
|
+
vi.mock('./4_ventilation.js', () => ({ default: vi.fn() }));
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
default: calc_deperdition,
|
|
29
|
+
Umur,
|
|
30
|
+
Uph,
|
|
31
|
+
Upb,
|
|
32
|
+
Ubv,
|
|
33
|
+
Uporte,
|
|
34
|
+
Upt
|
|
35
|
+
} = await import('./3_deperdition.js');
|
|
36
|
+
const { default: calc_mur } = await import('./3.2.1_mur.js');
|
|
37
|
+
const { default: calc_pont_thermique } = await import('./3.4_pont_thermique.js');
|
|
38
|
+
const { default: calc_ventilation } = await import('./4_ventilation.js');
|
|
39
|
+
|
|
40
|
+
let errorSpy;
|
|
41
|
+
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
vi.mocked(calc_mur).mockReset();
|
|
44
|
+
vi.mocked(calc_pont_thermique).mockReset();
|
|
45
|
+
vi.mocked(calc_ventilation).mockReset();
|
|
46
|
+
errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
afterEach(() => {
|
|
50
|
+
errorSpy.mockRestore();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 3. Déperditions de l'enveloppe : déperditions surfaciques par paroi.
|
|
55
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §3
|
|
56
|
+
*/
|
|
57
|
+
describe('déperditions surfaciques par paroi (U * surface * b)', () => {
|
|
58
|
+
test('Umur = surface_paroi_opaque * umur * b', () => {
|
|
59
|
+
const mur = {
|
|
60
|
+
donnee_entree: { surface_paroi_opaque: 10 },
|
|
61
|
+
donnee_intermediaire: { umur: 0.5, b: 1 }
|
|
62
|
+
};
|
|
63
|
+
expect(Umur(mur)).toBeCloseTo(5, 9);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('Uph = surface_paroi_opaque * uph * b', () => {
|
|
67
|
+
const ph = {
|
|
68
|
+
donnee_entree: { surface_paroi_opaque: 8 },
|
|
69
|
+
donnee_intermediaire: { uph: 0.2, b: 1 }
|
|
70
|
+
};
|
|
71
|
+
expect(Uph(ph)).toBeCloseTo(1.6, 9);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('Upb = surface_paroi_opaque * upb_final * b', () => {
|
|
75
|
+
const pb = {
|
|
76
|
+
donnee_entree: { surface_paroi_opaque: 12 },
|
|
77
|
+
donnee_intermediaire: { upb_final: 0.3, b: 1 }
|
|
78
|
+
};
|
|
79
|
+
expect(Upb(pb)).toBeCloseTo(3.6, 9);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('Ubv = surface_totale_baie * u_menuiserie * b', () => {
|
|
83
|
+
const bv = {
|
|
84
|
+
donnee_entree: { surface_totale_baie: 5 },
|
|
85
|
+
donnee_intermediaire: { u_menuiserie: 2, b: 1 }
|
|
86
|
+
};
|
|
87
|
+
expect(Ubv(bv)).toBeCloseTo(10, 9);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('Uporte = surface_porte * uporte * b', () => {
|
|
91
|
+
const porte = {
|
|
92
|
+
donnee_entree: { surface_porte: 2 },
|
|
93
|
+
donnee_intermediaire: { uporte: 1.5, b: 1 }
|
|
94
|
+
};
|
|
95
|
+
expect(Uporte(porte)).toBeCloseTo(3, 9);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('un coefficient de réduction b nul annule la déperdition de la paroi', () => {
|
|
99
|
+
const mur = {
|
|
100
|
+
donnee_entree: { surface_paroi_opaque: 10 },
|
|
101
|
+
donnee_intermediaire: { umur: 0.5, b: 0 }
|
|
102
|
+
};
|
|
103
|
+
expect(Umur(mur)).toBe(0);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* 3.4 Déperdition d'un pont thermique : Upt = l * k * pourcentage.
|
|
109
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §3.4
|
|
110
|
+
*/
|
|
111
|
+
describe('Upt - déperdition linéique des ponts thermiques', () => {
|
|
112
|
+
test("Upt = l * k lorsque le pourcentage n'est pas renseigné (défaut 1)", () => {
|
|
113
|
+
const pt = { donnee_entree: { l: 4 }, donnee_intermediaire: { k: 0.5 } };
|
|
114
|
+
expect(Upt(pt)).toBeCloseTo(2, 9);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('le pourcentage de prise en compte du pont thermique est appliqué', () => {
|
|
118
|
+
const pt = {
|
|
119
|
+
donnee_entree: { l: 4, pourcentage_valeur_pont_thermique: 0.5 },
|
|
120
|
+
donnee_intermediaire: { k: 0.5 }
|
|
121
|
+
};
|
|
122
|
+
expect(Upt(pt)).toBeCloseTo(1, 9);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
/** Fabrique un DPE minimal avec une enveloppe pré-calculée. */
|
|
127
|
+
function makeDpe({
|
|
128
|
+
mur = [],
|
|
129
|
+
pb = [],
|
|
130
|
+
ph = [],
|
|
131
|
+
bv = [],
|
|
132
|
+
porte = [],
|
|
133
|
+
pt = [],
|
|
134
|
+
ventilation = [],
|
|
135
|
+
deperdition_mur = 0,
|
|
136
|
+
deperdition_pont_thermique
|
|
137
|
+
} = {}) {
|
|
138
|
+
const deperdition = { deperdition_mur };
|
|
139
|
+
if (deperdition_pont_thermique !== undefined) {
|
|
140
|
+
deperdition.deperdition_pont_thermique = deperdition_pont_thermique;
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
numero_dpe: 'TEST',
|
|
144
|
+
logement: {
|
|
145
|
+
sortie: { deperdition },
|
|
146
|
+
enveloppe: {
|
|
147
|
+
mur_collection: { mur },
|
|
148
|
+
plancher_bas_collection: { plancher_bas: pb },
|
|
149
|
+
plancher_haut_collection: { plancher_haut: ph },
|
|
150
|
+
porte_collection: { porte },
|
|
151
|
+
baie_vitree_collection: { baie_vitree: bv },
|
|
152
|
+
pont_thermique_collection: { pont_thermique: pt }
|
|
153
|
+
},
|
|
154
|
+
ventilation_collection: { ventilation }
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Fabrique une paroi surfacique générique. */
|
|
160
|
+
function paroi(surfaceField, surface, uField, u, b, adjacence = '1') {
|
|
161
|
+
return {
|
|
162
|
+
donnee_entree: { [surfaceField]: surface, enum_type_adjacence_id: adjacence },
|
|
163
|
+
donnee_intermediaire: { [uField]: u, b }
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
describe("calc_deperdition - agrégation des déperditions de l'enveloppe", () => {
|
|
168
|
+
test('une enveloppe vide donne des déperditions nulles', () => {
|
|
169
|
+
const ret = calc_deperdition(
|
|
170
|
+
{ enum_periode_construction_id: '1' },
|
|
171
|
+
'h1a',
|
|
172
|
+
'th',
|
|
173
|
+
'0',
|
|
174
|
+
makeDpe(),
|
|
175
|
+
100
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
expect(ret.deperdition_enveloppe).toBe(0);
|
|
179
|
+
expect(ret.deperdition_renouvellement_air).toBe(0);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test("agrège les déperditions surfaciques, linéiques et de renouvellement d'air", () => {
|
|
183
|
+
const mur = [
|
|
184
|
+
{
|
|
185
|
+
donnee_entree: { surface_paroi_opaque: 10, enum_type_adjacence_id: '1' },
|
|
186
|
+
donnee_intermediaire: { umur: 0.5, b: 1 }
|
|
187
|
+
}
|
|
188
|
+
];
|
|
189
|
+
const ph = [
|
|
190
|
+
{
|
|
191
|
+
donnee_entree: { surface_paroi_opaque: 8, enum_type_adjacence_id: '1' },
|
|
192
|
+
donnee_intermediaire: { uph: 0.2, b: 1 }
|
|
193
|
+
}
|
|
194
|
+
];
|
|
195
|
+
const pb = [
|
|
196
|
+
{
|
|
197
|
+
donnee_entree: { surface_paroi_opaque: 12 },
|
|
198
|
+
donnee_intermediaire: { upb_final: 0.3, b: 1 }
|
|
199
|
+
}
|
|
200
|
+
];
|
|
201
|
+
const bv = [
|
|
202
|
+
{ donnee_entree: { surface_totale_baie: 5 }, donnee_intermediaire: { u_menuiserie: 2, b: 1 } }
|
|
203
|
+
];
|
|
204
|
+
const porte = [
|
|
205
|
+
{ donnee_entree: { surface_porte: 2 }, donnee_intermediaire: { uporte: 1.5, b: 1 } }
|
|
206
|
+
];
|
|
207
|
+
const pt = [{ donnee_entree: { l: 4 }, donnee_intermediaire: { k: 0.5 } }];
|
|
208
|
+
const ventilation = [{ donnee_intermediaire: { hvent: 40, hperm: 20 } }];
|
|
209
|
+
|
|
210
|
+
const dpe = makeDpe({ mur, ph, pb, bv, porte, pt, ventilation, deperdition_mur: 5 });
|
|
211
|
+
const ret = calc_deperdition({ enum_periode_construction_id: '1' }, 'h1a', 'th', '0', dpe, 100);
|
|
212
|
+
|
|
213
|
+
expect(ret.deperdition_mur).toBeCloseTo(5, 9);
|
|
214
|
+
expect(ret.deperdition_plancher_haut).toBeCloseTo(1.6, 9);
|
|
215
|
+
expect(ret.deperdition_plancher_bas).toBeCloseTo(3.6, 9);
|
|
216
|
+
expect(ret.deperdition_baie_vitree).toBeCloseTo(10, 9);
|
|
217
|
+
expect(ret.deperdition_porte).toBeCloseTo(3, 9);
|
|
218
|
+
expect(ret.deperdition_pont_thermique).toBeCloseTo(2, 9);
|
|
219
|
+
expect(ret.hvent).toBe(40);
|
|
220
|
+
expect(ret.hperm).toBe(20);
|
|
221
|
+
expect(ret.deperdition_renouvellement_air).toBe(60);
|
|
222
|
+
// 5 + 1,6 + 3,6 + 10 + 3 + 2 + 40 + 20
|
|
223
|
+
expect(ret.deperdition_enveloppe).toBeCloseTo(85.2, 9);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
test('chaque paroi est confiée à son module de calcul dédié', () => {
|
|
227
|
+
const mur = [
|
|
228
|
+
{
|
|
229
|
+
donnee_entree: { surface_paroi_opaque: 10, enum_type_adjacence_id: '1' },
|
|
230
|
+
donnee_intermediaire: { umur: 0.5, b: 1 }
|
|
231
|
+
}
|
|
232
|
+
];
|
|
233
|
+
const ventilation = [{ donnee_intermediaire: { hvent: 0, hperm: 0 } }];
|
|
234
|
+
const dpe = makeDpe({ mur, ventilation, deperdition_mur: 5 });
|
|
235
|
+
|
|
236
|
+
calc_deperdition({ enum_periode_construction_id: '1' }, 'h1a', 'th', '0', dpe, 100);
|
|
237
|
+
|
|
238
|
+
expect(calc_mur).toHaveBeenCalledTimes(1);
|
|
239
|
+
expect(calc_ventilation).toHaveBeenCalledTimes(1);
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* calc_Sdep (surface déperditive transmise à la ventilation) exclut les parois à coefficient
|
|
244
|
+
* b nul et les parois adjacentes à un local non déperditif. Les parois à déperdition nulle
|
|
245
|
+
* (b = 0) sont malgré tout parcourues par les réductions de déperdition (branche `|| 0`).
|
|
246
|
+
*/
|
|
247
|
+
test('calc_Sdep exclut les parois à b nul et les locaux non déperditifs', () => {
|
|
248
|
+
const mur = [
|
|
249
|
+
paroi('surface_paroi_opaque', 10, 'umur', 0.5, 0, '1'), // b = 0 => exclu de Sdep
|
|
250
|
+
paroi('surface_paroi_opaque', 20, 'umur', 0.4, 1, '2'), // local non déperditif => exclu
|
|
251
|
+
paroi('surface_paroi_opaque', 30, 'umur', 0.5, 1, '1') // pris en compte : +30
|
|
252
|
+
];
|
|
253
|
+
const ph = [
|
|
254
|
+
paroi('surface_paroi_opaque', 7, 'uph', 0.2, 0, '1'), // b = 0 => exclu de Sdep
|
|
255
|
+
paroi('surface_paroi_opaque', 8, 'uph', 0.2, 1, '1') // pris en compte : +8
|
|
256
|
+
];
|
|
257
|
+
const pb = [
|
|
258
|
+
paroi('surface_paroi_opaque', 6, 'upb_final', 0.3, 0), // b = 0 (branche `|| 0`)
|
|
259
|
+
paroi('surface_paroi_opaque', 12, 'upb_final', 0.3, 1)
|
|
260
|
+
];
|
|
261
|
+
const porte = [
|
|
262
|
+
{ donnee_entree: { surface_porte: 2 }, donnee_intermediaire: { uporte: 1.5, b: 0 } }, // exclu
|
|
263
|
+
{ donnee_entree: { surface_porte: 3 }, donnee_intermediaire: { uporte: 1.5, b: 1 } } // +3
|
|
264
|
+
];
|
|
265
|
+
const bv = [
|
|
266
|
+
{
|
|
267
|
+
donnee_entree: { surface_totale_baie: 5 },
|
|
268
|
+
donnee_intermediaire: { u_menuiserie: 2, b: 0 }
|
|
269
|
+
}, // exclu
|
|
270
|
+
{ donnee_entree: { surface_totale_baie: 4 }, donnee_intermediaire: { u_menuiserie: 2, b: 1 } } // +4
|
|
271
|
+
];
|
|
272
|
+
const ventilation = [{ donnee_intermediaire: { hvent: 0, hperm: 0 } }];
|
|
273
|
+
|
|
274
|
+
// d_mur = 0 + 20*0,4 + 30*0,5 = 23 (déclaré identique => conservé sans divergence)
|
|
275
|
+
const dpe = makeDpe({ mur, ph, pb, bv, porte, ventilation, deperdition_mur: 23 });
|
|
276
|
+
const ret = calc_deperdition({ enum_periode_construction_id: '1' }, 'h1a', 'th', '0', dpe, 100);
|
|
277
|
+
|
|
278
|
+
// Sdep transmis à calc_ventilation : 30 (mur) + 8 (ph) + 3 (porte) + 4 (bv) = 45
|
|
279
|
+
const sdepTransmis = vi.mocked(calc_ventilation).mock.calls[0][3];
|
|
280
|
+
expect(sdepTransmis).toBeCloseTo(45, 9);
|
|
281
|
+
|
|
282
|
+
expect(ret.deperdition_mur).toBeCloseTo(23, 9);
|
|
283
|
+
expect(ret.deperdition_plancher_haut).toBeCloseTo(1.6, 9); // 0 + 8*0,2
|
|
284
|
+
expect(ret.deperdition_plancher_bas).toBeCloseTo(3.6, 9); // 0 + 12*0,3
|
|
285
|
+
expect(ret.deperdition_porte).toBeCloseTo(4.5, 9); // 0 + 3*1,5
|
|
286
|
+
expect(ret.deperdition_baie_vitree).toBeCloseTo(8, 9); // 0 + 4*2
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Collections d'enveloppe absentes : chaque liste retombe sur son tableau vide par défaut
|
|
291
|
+
* (`|| []`) et l'agrégation produit des déperditions nulles.
|
|
292
|
+
*/
|
|
293
|
+
test('collections absentes : chaque liste retombe sur un tableau vide', () => {
|
|
294
|
+
const dpe = {
|
|
295
|
+
numero_dpe: 'TEST',
|
|
296
|
+
logement: {
|
|
297
|
+
sortie: { deperdition: { deperdition_mur: 0 } },
|
|
298
|
+
enveloppe: {
|
|
299
|
+
mur_collection: {},
|
|
300
|
+
plancher_bas_collection: {},
|
|
301
|
+
plancher_haut_collection: {},
|
|
302
|
+
porte_collection: {},
|
|
303
|
+
baie_vitree_collection: {},
|
|
304
|
+
pont_thermique_collection: {}
|
|
305
|
+
},
|
|
306
|
+
ventilation_collection: {}
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
const ret = calc_deperdition({ enum_periode_construction_id: '1' }, 'h1a', 'th', '0', dpe, 100);
|
|
311
|
+
expect(ret.deperdition_enveloppe).toBe(0);
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* 3.4 Comparaison des déperditions calculées et déclarées.
|
|
317
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §3.4
|
|
318
|
+
*/
|
|
319
|
+
describe('totalDeperditionMurs - arbitrage entre valeur calculée et déclarée', () => {
|
|
320
|
+
/** Un mur unique : Umur = 10 * 0,5 * 1 = 5. */
|
|
321
|
+
const mur = () => [
|
|
322
|
+
{
|
|
323
|
+
donnee_entree: { surface_paroi_opaque: 10, enum_type_adjacence_id: '1' },
|
|
324
|
+
donnee_intermediaire: { umur: 0.5, b: 1 }
|
|
325
|
+
}
|
|
326
|
+
];
|
|
327
|
+
|
|
328
|
+
test('déclaré supérieur au calculé : le total déclaré est conservé', () => {
|
|
329
|
+
const dpe = makeDpe({
|
|
330
|
+
mur: mur(),
|
|
331
|
+
ventilation: [{ donnee_intermediaire: { hvent: 0, hperm: 0 } }],
|
|
332
|
+
deperdition_mur: 6
|
|
333
|
+
});
|
|
334
|
+
const ret = calc_deperdition({ enum_periode_construction_id: '1' }, 'h1a', 'th', '0', dpe, 100);
|
|
335
|
+
|
|
336
|
+
expect(ret.deperdition_mur).toBe(6);
|
|
337
|
+
expect(errorSpy).toHaveBeenCalled();
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
test('déclaré inférieur au calculé : le total calculé est conservé', () => {
|
|
341
|
+
const dpe = makeDpe({
|
|
342
|
+
mur: mur(),
|
|
343
|
+
ventilation: [{ donnee_intermediaire: { hvent: 0, hperm: 0 } }],
|
|
344
|
+
deperdition_mur: 4
|
|
345
|
+
});
|
|
346
|
+
const ret = calc_deperdition({ enum_periode_construction_id: '1' }, 'h1a', 'th', '0', dpe, 100);
|
|
347
|
+
|
|
348
|
+
expect(ret.deperdition_mur).toBeCloseTo(5, 9);
|
|
349
|
+
expect(errorSpy).toHaveBeenCalled();
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
describe('totalDeperditionPontThermique - arbitrage entre valeur calculée et déclarée', () => {
|
|
354
|
+
/**
|
|
355
|
+
* Ponts thermiques calculés identiques aux déclarés (mêmes k) mais total déclaré divergent :
|
|
356
|
+
* le total déclaré est conservé. Le premier pont thermique (l = 0) exerce la branche `|| 0`
|
|
357
|
+
* de la réduction, le second porte un pourcentage de prise en compte.
|
|
358
|
+
*/
|
|
359
|
+
test('ponts thermiques identiques mais total déclaré divergent : total déclaré conservé', () => {
|
|
360
|
+
const pt = [
|
|
361
|
+
{ donnee_entree: { l: 0 }, donnee_intermediaire: { k: 0 } }, // Upt = 0 (branche `|| 0`)
|
|
362
|
+
{
|
|
363
|
+
donnee_entree: { l: 4, pourcentage_valeur_pont_thermique: 0.5 },
|
|
364
|
+
donnee_intermediaire: { k: 0.5 }
|
|
365
|
+
} // Upt = 4 * 0,5 * 0,5 = 1
|
|
366
|
+
];
|
|
367
|
+
const dpe = makeDpe({
|
|
368
|
+
pt,
|
|
369
|
+
ventilation: [{ donnee_intermediaire: { hvent: 0, hperm: 0 } }],
|
|
370
|
+
deperdition_pont_thermique: 3 // total calculé = 1, déclaré = 3
|
|
371
|
+
});
|
|
372
|
+
const ret = calc_deperdition({ enum_periode_construction_id: '1' }, 'h1a', 'th', '0', dpe, 100);
|
|
373
|
+
|
|
374
|
+
expect(ret.deperdition_pont_thermique).toBe(3);
|
|
375
|
+
expect(errorSpy).toHaveBeenCalled();
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Lorsque les ponts thermiques calculés diffèrent des déclarés (module de calcul modifiant k),
|
|
380
|
+
* la comparaison échoue et le total calculé est utilisé.
|
|
381
|
+
*/
|
|
382
|
+
test('ponts thermiques calculés divergents des déclarés : total calculé conservé', () => {
|
|
383
|
+
vi.mocked(calc_pont_thermique).mockImplementation((pt) => {
|
|
384
|
+
pt.donnee_intermediaire.k = 0.8;
|
|
385
|
+
});
|
|
386
|
+
const pt = [{ donnee_entree: { l: 4 }, donnee_intermediaire: { k: 0.5 } }];
|
|
387
|
+
const dpe = makeDpe({
|
|
388
|
+
pt,
|
|
389
|
+
ventilation: [{ donnee_intermediaire: { hvent: 0, hperm: 0 } }],
|
|
390
|
+
deperdition_pont_thermique: 5
|
|
391
|
+
});
|
|
392
|
+
const ret = calc_deperdition({ enum_periode_construction_id: '1' }, 'h1a', 'th', '0', dpe, 100);
|
|
393
|
+
|
|
394
|
+
// Upt = 4 * 0,8 * 1 = 3,2 (valeur calculée, différente du déclaré 5)
|
|
395
|
+
expect(ret.deperdition_pont_thermique).toBeCloseTo(3.2, 9);
|
|
396
|
+
});
|
|
397
|
+
});
|
package/4_ventilation.js
CHANGED
|
@@ -120,7 +120,7 @@ const f_tab = {
|
|
|
120
120
|
0: 20
|
|
121
121
|
};
|
|
122
122
|
|
|
123
|
-
function calc_hperm(di, surface_ventile, Hsp, Sdep, pfe) {
|
|
123
|
+
export function calc_hperm(di, surface_ventile, Hsp, Sdep, pfe) {
|
|
124
124
|
const e = e_tab[pfe];
|
|
125
125
|
const f = f_tab[pfe];
|
|
126
126
|
const Q4pa_env = di.q4pa_conv * Sdep;
|