@open3cl/engine 1.6.0 → 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/README.md +18 -9
- 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 +7 -5
- 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
package/9_chauffage.spec.js
CHANGED
|
@@ -1,102 +1,488 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
1
|
+
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Dépendances mockées pour isoler `9_chauffage.js` :
|
|
5
|
+
* - `utils` : `requestInput`, `tv`, `tvColumnIDs` et la table `Tbase` ;
|
|
6
|
+
* - `9_emetteur_ch` : `calc_emetteur_ch` (renseignement des émetteurs) ;
|
|
7
|
+
* - `9_generateur_ch` : `calc_generateur_ch` (consommations, piloté par un
|
|
8
|
+
* espion qui écrit les données intermédiaires), `checkForGeneratorType`
|
|
9
|
+
* (classification combustion/PAC) et `hasConsoForAuxDistribution` ;
|
|
10
|
+
* - `13.2_generateur_combustion` / `13.2_generateur_combustion_ch` : calculs de
|
|
11
|
+
* combustion (no-op espionnés).
|
|
12
|
+
*
|
|
13
|
+
* On vérifie la logique d'orchestration propre au module : mise à l'échelle du
|
|
14
|
+
* besoin, facteur de couverture solaire, prorata entre générateurs (cascade,
|
|
15
|
+
* hybride) et répartition des auxiliaires.
|
|
16
|
+
*/
|
|
17
|
+
vi.mock('./utils.js', () => ({
|
|
18
|
+
requestInput: vi.fn(),
|
|
19
|
+
tv: vi.fn(),
|
|
20
|
+
tvColumnIDs: vi.fn(),
|
|
21
|
+
Tbase: {
|
|
22
|
+
ca1: { h1: -9.5, h2: -6, h3: -3 },
|
|
23
|
+
ca2: { h1: -11 }
|
|
24
|
+
}
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
vi.mock('./9_emetteur_ch.js', () => ({
|
|
28
|
+
calc_emetteur_ch: vi.fn()
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
vi.mock('./9_generateur_ch.js', () => ({
|
|
32
|
+
calc_generateur_ch: vi.fn(),
|
|
33
|
+
checkForGeneratorType: vi.fn(),
|
|
34
|
+
hasConsoForAuxDistribution: vi.fn()
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
vi.mock('./13.2_generateur_combustion.js', () => ({
|
|
38
|
+
tv_generateur_combustion: vi.fn()
|
|
39
|
+
}));
|
|
40
|
+
|
|
41
|
+
vi.mock('./13.2_generateur_combustion_ch.js', () => ({
|
|
42
|
+
tv_temp_fonc_30_100: vi.fn()
|
|
43
|
+
}));
|
|
44
|
+
|
|
45
|
+
vi.mock('./enums.js', () => ({
|
|
46
|
+
default: {
|
|
47
|
+
classe_altitude: { 1: 'ca1', 2: 'ca2' },
|
|
48
|
+
zone_climatique: { 1: 'h1a', 2: 'h2b', 3: 'h3c' }
|
|
49
|
+
}
|
|
50
|
+
}));
|
|
51
|
+
|
|
52
|
+
const { default: calc_chauffage, tauxChargeForGenerator } = await import('./9_chauffage.js');
|
|
53
|
+
const { requestInput, tv, tvColumnIDs } = await import('./utils.js');
|
|
54
|
+
const { calc_emetteur_ch } = await import('./9_emetteur_ch.js');
|
|
55
|
+
const { calc_generateur_ch, checkForGeneratorType, hasConsoForAuxDistribution } = await import(
|
|
56
|
+
'./9_generateur_ch.js'
|
|
57
|
+
);
|
|
58
|
+
const { tv_generateur_combustion } = await import('./13.2_generateur_combustion.js');
|
|
59
|
+
const { tv_temp_fonc_30_100 } = await import('./13.2_generateur_combustion_ch.js');
|
|
60
|
+
|
|
61
|
+
/** calc_generateur_ch mocké : écrit des consommations déterministes. */
|
|
62
|
+
function stubGenerateur({ conso = 100, consoDep = 120, auxDistribution } = {}) {
|
|
63
|
+
vi.mocked(calc_generateur_ch).mockImplementation((_dpe, gen) => {
|
|
64
|
+
gen.donnee_intermediaire = gen.donnee_intermediaire || {};
|
|
65
|
+
gen.donnee_intermediaire.conso_ch = conso;
|
|
66
|
+
gen.donnee_intermediaire.conso_ch_depensier = consoDep;
|
|
67
|
+
if (auxDistribution !== undefined) {
|
|
68
|
+
gen.donnee_intermediaire.conso_auxiliaire_distribution_ch = auxDistribution;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Émetteur minimal. */
|
|
74
|
+
function emetteur(lien = '1') {
|
|
75
|
+
return { donnee_entree: { enum_lien_generateur_emetteur_id: lien } };
|
|
76
|
+
}
|
|
73
77
|
|
|
74
|
-
|
|
78
|
+
/** Générateur minimal. */
|
|
79
|
+
function generateur(de = {}, di = {}) {
|
|
80
|
+
return {
|
|
81
|
+
donnee_entree: {
|
|
82
|
+
enum_type_generateur_ch_id: '98',
|
|
83
|
+
enum_lien_generateur_emetteur_id: '1',
|
|
84
|
+
...de
|
|
85
|
+
},
|
|
86
|
+
donnee_intermediaire: di
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Installation de chauffage minimale. */
|
|
91
|
+
function installation(gens, ems, deOverrides = {}) {
|
|
92
|
+
return {
|
|
93
|
+
donnee_entree: {
|
|
94
|
+
surface_chauffee: 100,
|
|
95
|
+
enum_cfg_installation_ch_id: '1',
|
|
96
|
+
...deOverrides
|
|
97
|
+
},
|
|
98
|
+
emetteur_chauffage_collection: { emetteur_chauffage: ems },
|
|
99
|
+
generateur_chauffage_collection: { generateur_chauffage: gens }
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** DPE minimal (enveloppe non exploitée ici, calc_generateur_ch mocké). */
|
|
104
|
+
const dpe = { logement: { enveloppe: {} } };
|
|
105
|
+
|
|
106
|
+
/** Appel standard de calc_chauffage. */
|
|
107
|
+
function appel(ch, overrides = {}) {
|
|
108
|
+
const args = {
|
|
109
|
+
ca_id: 1,
|
|
110
|
+
zc_id: 1,
|
|
111
|
+
inertie_id: 3,
|
|
112
|
+
map_id: 2,
|
|
113
|
+
bch: 1000,
|
|
114
|
+
bch_dep: 1200,
|
|
115
|
+
GV: 150,
|
|
116
|
+
Sh: 100,
|
|
117
|
+
hsp: 2.5,
|
|
118
|
+
ac: 1,
|
|
119
|
+
ilpa: 0,
|
|
120
|
+
besoin_ch_mois: {},
|
|
121
|
+
...overrides
|
|
122
|
+
};
|
|
123
|
+
calc_chauffage(
|
|
124
|
+
dpe,
|
|
125
|
+
ch,
|
|
126
|
+
args.ca_id,
|
|
127
|
+
args.zc_id,
|
|
128
|
+
args.inertie_id,
|
|
129
|
+
args.map_id,
|
|
130
|
+
args.bch,
|
|
131
|
+
args.bch_dep,
|
|
132
|
+
args.GV,
|
|
133
|
+
args.Sh,
|
|
134
|
+
args.hsp,
|
|
135
|
+
args.ac,
|
|
136
|
+
args.ilpa,
|
|
137
|
+
args.besoin_ch_mois
|
|
138
|
+
);
|
|
139
|
+
return args;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
beforeEach(() => {
|
|
143
|
+
vi.mocked(requestInput).mockReset();
|
|
144
|
+
vi.mocked(tv).mockReset();
|
|
145
|
+
vi.mocked(tvColumnIDs).mockReset();
|
|
146
|
+
vi.mocked(calc_emetteur_ch).mockReset();
|
|
147
|
+
vi.mocked(calc_generateur_ch).mockReset();
|
|
148
|
+
vi.mocked(checkForGeneratorType).mockReset();
|
|
149
|
+
vi.mocked(hasConsoForAuxDistribution).mockReset();
|
|
150
|
+
vi.mocked(tv_generateur_combustion).mockReset();
|
|
151
|
+
vi.mocked(tv_temp_fonc_30_100).mockReset();
|
|
152
|
+
|
|
153
|
+
// valeurs par défaut : générateur ni combustion ni PAC, pas d'auxiliaire
|
|
154
|
+
vi.mocked(checkForGeneratorType).mockImplementation((_dpe, _de, _di, du) => {
|
|
155
|
+
du.isCombustionGenerator = false;
|
|
156
|
+
});
|
|
157
|
+
vi.mocked(hasConsoForAuxDistribution).mockReturnValue(false);
|
|
158
|
+
vi.mocked(requestInput).mockReturnValue('installation de chauffage simple');
|
|
159
|
+
vi.mocked(tv).mockReturnValue({ facteur_couverture_solaire: '0.4' });
|
|
160
|
+
stubGenerateur();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* 9. Consommation de chauffage — orchestration
|
|
165
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §9
|
|
166
|
+
*/
|
|
167
|
+
describe('calc_chauffage - cas nominal (1 générateur, 1 émetteur)', () => {
|
|
168
|
+
test('agrège les consommations et renseigne les données intermédiaires', () => {
|
|
169
|
+
const ch = installation([generateur()], [emetteur('1')]);
|
|
170
|
+
appel(ch);
|
|
75
171
|
|
|
76
172
|
expect(ch.donnee_intermediaire).toStrictEqual({
|
|
77
|
-
besoin_ch:
|
|
78
|
-
besoin_ch_depensier:
|
|
79
|
-
conso_ch:
|
|
80
|
-
conso_ch_depensier:
|
|
173
|
+
besoin_ch: 1000,
|
|
174
|
+
besoin_ch_depensier: 1200,
|
|
175
|
+
conso_ch: 100,
|
|
176
|
+
conso_ch_depensier: 120
|
|
81
177
|
});
|
|
178
|
+
expect(ch.donnee_utilisateur.Pnominal).toBe(0);
|
|
179
|
+
expect(calc_emetteur_ch).toHaveBeenCalledTimes(1);
|
|
180
|
+
expect(checkForGeneratorType).toHaveBeenCalledTimes(1);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test('renseigne les valeurs par défaut du générateur (fch, ratios, surface)', () => {
|
|
184
|
+
const ch = installation([generateur()], [emetteur('1')]);
|
|
185
|
+
appel(ch);
|
|
186
|
+
|
|
187
|
+
const genDe = ch.generateur_chauffage_collection.generateur_chauffage[0].donnee_entree;
|
|
188
|
+
// Fch issu de la table de couverture solaire (0.4)
|
|
189
|
+
expect(genDe.fch).toBe(0.4);
|
|
190
|
+
expect(genDe.ratio_virtualisation).toBe(1);
|
|
191
|
+
expect(genDe.cle_repartition_ch).toBe(1);
|
|
192
|
+
expect(genDe.nombre_niveau_installation_ch).toBe(1);
|
|
193
|
+
expect(genDe.surface_chauffee).toBe(100);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test('conserve les valeurs déjà présentes sur le générateur', () => {
|
|
197
|
+
const ch = installation([generateur()], [emetteur('1')], {});
|
|
198
|
+
// valeurs propres sur l'installation
|
|
199
|
+
ch.donnee_entree.ratio_virtualisation = 2;
|
|
200
|
+
ch.donnee_entree.cle_repartition_ch = 3;
|
|
201
|
+
ch.donnee_entree.nombre_niveau_installation_ch = 4;
|
|
202
|
+
appel(ch);
|
|
203
|
+
|
|
204
|
+
const genDe = ch.generateur_chauffage_collection.generateur_chauffage[0].donnee_entree;
|
|
205
|
+
expect(genDe.ratio_virtualisation).toBe(2);
|
|
206
|
+
expect(genDe.cle_repartition_ch).toBe(3);
|
|
207
|
+
expect(genDe.nombre_niveau_installation_ch).toBe(4);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test('prorata unitaire : le besoin complet est transmis au générateur', () => {
|
|
211
|
+
const ch = installation([generateur()], [emetteur('1')]);
|
|
212
|
+
appel(ch, { bch: 800 });
|
|
213
|
+
// 6e argument de calc_generateur_ch = bch * prorata (= 800 * 1)
|
|
214
|
+
expect(vi.mocked(calc_generateur_ch).mock.calls[0][5]).toBe(800);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
describe('calc_chauffage - mise à l’échelle du besoin selon la surface', () => {
|
|
219
|
+
test('besoin ajusté au prorata surface_chauffee / Sh quand elles diffèrent', () => {
|
|
220
|
+
const ch = installation([generateur()], [emetteur('1')]);
|
|
221
|
+
ch.donnee_entree.surface_chauffee = 50;
|
|
222
|
+
appel(ch, { bch: 1000, Sh: 100 });
|
|
223
|
+
// bch mis à l'échelle : 1000 * 50 / 100 = 500 transmis au générateur
|
|
224
|
+
expect(vi.mocked(calc_generateur_ch).mock.calls[0][5]).toBe(500);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test('surface d’installation absente : la surface habitable Sh sert de repli', () => {
|
|
228
|
+
const ch = installation([generateur()], [emetteur('1')], { surface_chauffee: 0 });
|
|
229
|
+
appel(ch, { Sh: 120 });
|
|
230
|
+
// de.surface_chauffee falsy => genChDe.surface_chauffee = Sh
|
|
82
231
|
expect(
|
|
83
|
-
ch.
|
|
84
|
-
).
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
232
|
+
ch.generateur_chauffage_collection.generateur_chauffage[0].donnee_entree.surface_chauffee
|
|
233
|
+
).toBe(120);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
describe('calc_chauffage - facteur de couverture solaire (Fch)', () => {
|
|
238
|
+
test('facteur saisi directement pris tel quel', () => {
|
|
239
|
+
const ch = installation([generateur()], [emetteur('1')]);
|
|
240
|
+
ch.donnee_entree.fch_saisi = 0.7;
|
|
241
|
+
appel(ch);
|
|
242
|
+
expect(ch.generateur_chauffage_collection.generateur_chauffage[0].donnee_entree.fch).toBe(0.7);
|
|
243
|
+
expect(tv).not.toHaveBeenCalled();
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
test('facteur lu en table quand non saisi', () => {
|
|
247
|
+
const ch = installation([generateur()], [emetteur('1')]);
|
|
248
|
+
vi.mocked(tv).mockReturnValue({ facteur_couverture_solaire: '0.55' });
|
|
249
|
+
appel(ch);
|
|
250
|
+
expect(ch.generateur_chauffage_collection.generateur_chauffage[0].donnee_entree.fch).toBe(0.55);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test('aucune ligne trouvée : Fch nul, repli sur 0.5 et message d’erreur', () => {
|
|
254
|
+
const err = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
255
|
+
const ch = installation([generateur()], [emetteur('1')]);
|
|
256
|
+
vi.mocked(tv).mockReturnValue(null);
|
|
257
|
+
appel(ch);
|
|
258
|
+
// Fch = null => genChDe.fch = null || 0.5
|
|
259
|
+
expect(ch.generateur_chauffage_collection.generateur_chauffage[0].donnee_entree.fch).toBe(0.5);
|
|
260
|
+
expect(err).toHaveBeenCalled();
|
|
261
|
+
err.mockRestore();
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
describe('calc_chauffage - générateurs à combustion', () => {
|
|
266
|
+
beforeEach(() => {
|
|
267
|
+
vi.mocked(checkForGeneratorType).mockImplementation((_dpe, _de, _di, du) => {
|
|
268
|
+
du.isCombustionGenerator = true;
|
|
89
269
|
});
|
|
270
|
+
vi.mocked(tvColumnIDs).mockReturnValue(['5']);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
test('méthode de saisie ≠ 5 : recalcul des températures de fonctionnement', () => {
|
|
274
|
+
const ch = installation(
|
|
275
|
+
[generateur({ enum_type_generateur_ch_id: '5', enum_methode_saisie_carac_sys_id: '1' })],
|
|
276
|
+
[emetteur('1')]
|
|
277
|
+
);
|
|
278
|
+
appel(ch);
|
|
279
|
+
expect(tv_generateur_combustion).toHaveBeenCalled();
|
|
280
|
+
expect(tv_temp_fonc_30_100).toHaveBeenCalled();
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test('méthode 5 avec températures déjà connues : pas de recalcul', () => {
|
|
284
|
+
const ch = installation(
|
|
285
|
+
[
|
|
286
|
+
generateur(
|
|
287
|
+
{ enum_type_generateur_ch_id: '5', enum_methode_saisie_carac_sys_id: '5' },
|
|
288
|
+
{ temp_fonc_30: 30, temp_fonc_100: 45 }
|
|
289
|
+
)
|
|
290
|
+
],
|
|
291
|
+
[emetteur('1')]
|
|
292
|
+
);
|
|
293
|
+
appel(ch);
|
|
294
|
+
expect(tv_temp_fonc_30_100).not.toHaveBeenCalled();
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
test('méthode 5 mais temp_fonc_30 manquante : recalcul', () => {
|
|
298
|
+
const ch = installation(
|
|
299
|
+
[
|
|
300
|
+
generateur(
|
|
301
|
+
{ enum_type_generateur_ch_id: '5', enum_methode_saisie_carac_sys_id: '5' },
|
|
302
|
+
{ temp_fonc_100: 45 }
|
|
303
|
+
)
|
|
304
|
+
],
|
|
305
|
+
[emetteur('1')]
|
|
306
|
+
);
|
|
307
|
+
appel(ch);
|
|
308
|
+
expect(tv_temp_fonc_30_100).toHaveBeenCalled();
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test('méthode 5 mais temp_fonc_100 manquante : recalcul', () => {
|
|
312
|
+
const ch = installation(
|
|
313
|
+
[
|
|
314
|
+
generateur(
|
|
315
|
+
{ enum_type_generateur_ch_id: '5', enum_methode_saisie_carac_sys_id: '5' },
|
|
316
|
+
{ temp_fonc_30: 30 }
|
|
317
|
+
)
|
|
318
|
+
],
|
|
319
|
+
[emetteur('1')]
|
|
320
|
+
);
|
|
321
|
+
appel(ch);
|
|
322
|
+
expect(tv_temp_fonc_30_100).toHaveBeenCalled();
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
test('type de générateur hors table temp_fonc_30 : pas de recalcul de températures', () => {
|
|
326
|
+
const ch = installation(
|
|
327
|
+
[generateur({ enum_type_generateur_ch_id: '99', enum_methode_saisie_carac_sys_id: '1' })],
|
|
328
|
+
[emetteur('1')]
|
|
329
|
+
);
|
|
330
|
+
appel(ch);
|
|
331
|
+
expect(tv_generateur_combustion).toHaveBeenCalled();
|
|
332
|
+
expect(tv_temp_fonc_30_100).not.toHaveBeenCalled();
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
test('deux générateurs à combustion en cascade : prorata au prorata des puissances', () => {
|
|
336
|
+
const gen1 = generateur({ enum_type_generateur_ch_id: '5' }, { pn: 3000 });
|
|
337
|
+
const gen2 = generateur({ enum_type_generateur_ch_id: '5' }, { pn: 1000 });
|
|
338
|
+
const ch = installation([gen1, gen2], [emetteur('1')], {
|
|
339
|
+
enum_cfg_installation_ch_id: '1'
|
|
340
|
+
});
|
|
341
|
+
appel(ch, { bch: 1000 });
|
|
342
|
+
|
|
343
|
+
// Pnominal = 4000 ; prorata gen1 = 3000/4000, gen2 = 1000/4000
|
|
344
|
+
expect(ch.donnee_utilisateur.Pnominal).toBe(4000);
|
|
345
|
+
expect(vi.mocked(calc_generateur_ch).mock.calls[0][5]).toBeCloseTo(750, 9);
|
|
346
|
+
expect(vi.mocked(calc_generateur_ch).mock.calls[1][5]).toBeCloseTo(250, 9);
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
describe('calc_chauffage - prorata entre générateurs', () => {
|
|
351
|
+
test('configuration ≠ 1 : prorata neutre (1 / (0 || 1))', () => {
|
|
352
|
+
const ch = installation([generateur()], [emetteur('1')], {
|
|
353
|
+
enum_cfg_installation_ch_id: '2'
|
|
354
|
+
});
|
|
355
|
+
appel(ch, { bch: 900 });
|
|
356
|
+
// nbCascadeForSameEmetteur = 0 => prorata = 1 / (0 || 1) = 1
|
|
357
|
+
expect(vi.mocked(calc_generateur_ch).mock.calls[0][5]).toBe(900);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
test('plusieurs émetteurs pour le même lien : pas de cascade (nbEmetteur ≠ 1)', () => {
|
|
361
|
+
const ch = installation(
|
|
362
|
+
[generateur({ enum_lien_generateur_emetteur_id: '1' })],
|
|
363
|
+
[emetteur('1'), emetteur('1')],
|
|
364
|
+
{ enum_cfg_installation_ch_id: '1' }
|
|
365
|
+
);
|
|
366
|
+
appel(ch, { bch: 900 });
|
|
367
|
+
// nbEmetteur = 2 => nbCascadeForSameEmetteur = 0 => prorata = 1
|
|
368
|
+
expect(vi.mocked(calc_generateur_ch).mock.calls[0][5]).toBe(900);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
test('générateur PAC hybride avec scop : part PAC (0.8 en zone H1)', () => {
|
|
372
|
+
const gen = generateur({ enum_type_generateur_ch_id: '150' }, { scop: 3.5 });
|
|
373
|
+
const ch = installation([gen], [emetteur('1')]);
|
|
374
|
+
appel(ch, { bch: 1000, zc_id: 1 });
|
|
375
|
+
// hybrideProrata h1 pac = 0.8
|
|
376
|
+
expect(vi.mocked(calc_generateur_ch).mock.calls[0][5]).toBeCloseTo(800, 9);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
test('générateur PAC hybride sans scop/cop : part chaudière (0.2 en zone H1)', () => {
|
|
380
|
+
const gen = generateur({ enum_type_generateur_ch_id: '150' }, {});
|
|
381
|
+
const ch = installation([gen], [emetteur('1')]);
|
|
382
|
+
appel(ch, { bch: 1000, zc_id: 1 });
|
|
383
|
+
// hybrideProrata h1 chaudiere = 0.2
|
|
384
|
+
expect(vi.mocked(calc_generateur_ch).mock.calls[0][5]).toBeCloseTo(200, 9);
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
describe('calc_chauffage - auxiliaires de distribution répartis', () => {
|
|
389
|
+
test('répartition de la consommation d’auxiliaires sur les générateurs éligibles', () => {
|
|
390
|
+
vi.mocked(hasConsoForAuxDistribution).mockReturnValue(true);
|
|
391
|
+
stubGenerateur({ auxDistribution: 400 });
|
|
392
|
+
|
|
393
|
+
const ch = installation(
|
|
394
|
+
[
|
|
395
|
+
generateur({ enum_type_generateur_ch_id: '110' }),
|
|
396
|
+
generateur({ enum_type_generateur_ch_id: '110' })
|
|
397
|
+
],
|
|
398
|
+
[emetteur('1')],
|
|
399
|
+
{ enum_cfg_installation_ch_id: '2' }
|
|
400
|
+
);
|
|
401
|
+
appel(ch);
|
|
402
|
+
|
|
403
|
+
// 2 générateurs éligibles => 400 / 2 = 200 chacun
|
|
404
|
+
const gens = ch.generateur_chauffage_collection.generateur_chauffage;
|
|
405
|
+
expect(gens[0].donnee_intermediaire.conso_auxiliaire_distribution_ch).toBe(200);
|
|
406
|
+
expect(gens[1].donnee_intermediaire.conso_auxiliaire_distribution_ch).toBe(200);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
test('aucun auxiliaire de distribution : pas de division', () => {
|
|
410
|
+
const ch = installation([generateur()], [emetteur('1')]);
|
|
411
|
+
appel(ch);
|
|
412
|
+
// conso_auxiliaire_distribution_ch non défini par le stub => aucune répartition
|
|
90
413
|
expect(
|
|
91
414
|
ch.generateur_chauffage_collection.generateur_chauffage[0].donnee_intermediaire
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
415
|
+
.conso_auxiliaire_distribution_ch
|
|
416
|
+
).toBeUndefined();
|
|
417
|
+
});
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
describe('calc_chauffage - initialisation défensive des données du générateur', () => {
|
|
421
|
+
test('générateur sans donnee_utilisateur ni donnee_intermediaire initiales', () => {
|
|
422
|
+
const gen = {
|
|
423
|
+
donnee_entree: { enum_type_generateur_ch_id: '98', enum_lien_generateur_emetteur_id: '1' }
|
|
424
|
+
};
|
|
425
|
+
const ch = installation([gen], [emetteur('1')]);
|
|
426
|
+
appel(ch);
|
|
427
|
+
expect(gen.donnee_utilisateur.nbGenerateurCascade).toBe(1);
|
|
428
|
+
expect(gen.donnee_intermediaire.conso_ch).toBe(100);
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* 13.2.1.2 Taux de charge des générateurs à combustion (cdimref)
|
|
434
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.1.2
|
|
435
|
+
*/
|
|
436
|
+
describe('tauxChargeForGenerator - taux de charge des générateurs à combustion', () => {
|
|
437
|
+
/** Installation avec un générateur à combustion. */
|
|
438
|
+
function installCombustion(pnominal = 5000, rdim) {
|
|
439
|
+
return {
|
|
440
|
+
donnee_entree: { rdim },
|
|
441
|
+
donnee_utilisateur: { Pnominal: pnominal },
|
|
442
|
+
generateur_chauffage_collection: {
|
|
443
|
+
generateur_chauffage: [{ donnee_utilisateur: { isCombustionGenerator: true } }]
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
test('maison : GV utilisé directement pour le calcul du taux de charge', () => {
|
|
449
|
+
const install = installCombustion(5000);
|
|
450
|
+
tauxChargeForGenerator([install], 200, 1, 1, 'maison');
|
|
451
|
+
|
|
452
|
+
const gen = install.generateur_chauffage_collection.generateur_chauffage[0];
|
|
453
|
+
// cdimref = Pn / (GV * (19 - tbase)) ; tbase = -9.5 (ca1/h1)
|
|
454
|
+
expect(gen.donnee_utilisateur.cdimref).toBeCloseTo(5000 / (200 * (19 + 9.5)), 9);
|
|
455
|
+
expect(gen.donnee_utilisateur.cdimrefDep).toBeCloseTo(5000 / (200 * (21 + 9.5)), 9);
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
test('immeuble : GV corrigé par le ratio de dimensionnement rdim', () => {
|
|
459
|
+
const install = installCombustion(5000, 2);
|
|
460
|
+
tauxChargeForGenerator([install], 200, 1, 1, 'immeuble');
|
|
461
|
+
|
|
462
|
+
const gen = install.generateur_chauffage_collection.generateur_chauffage[0];
|
|
463
|
+
const gvRatio = 200 * (1 / 2);
|
|
464
|
+
expect(gen.donnee_utilisateur.cdimref).toBeCloseTo(5000 / (gvRatio * (19 + 9.5)), 9);
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
test('immeuble sans rdim : ratio de dimensionnement par défaut (1)', () => {
|
|
468
|
+
const install = installCombustion(5000);
|
|
469
|
+
tauxChargeForGenerator([install], 200, 1, 1, 'immeuble');
|
|
470
|
+
|
|
471
|
+
const gen = install.generateur_chauffage_collection.generateur_chauffage[0];
|
|
472
|
+
// rdim absent => GV_ratio = GV
|
|
473
|
+
expect(gen.donnee_utilisateur.cdimref).toBeCloseTo(5000 / (200 * (19 + 9.5)), 9);
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
test('installation sans générateur à combustion : ignorée', () => {
|
|
477
|
+
const installSans = {
|
|
478
|
+
donnee_entree: {},
|
|
479
|
+
donnee_utilisateur: {},
|
|
480
|
+
generateur_chauffage_collection: {
|
|
481
|
+
generateur_chauffage: [{ donnee_utilisateur: { isCombustionGenerator: false } }]
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
// aucune erreur, aucune donnée de taux de charge écrite
|
|
485
|
+
expect(() => tauxChargeForGenerator([installSans], 200, 1, 1, 'maison')).not.toThrow();
|
|
486
|
+
expect(installSans.donnee_utilisateur.genCombustion).toBeUndefined();
|
|
101
487
|
});
|
|
102
488
|
});
|