@open3cl/engine 1.8.8 → 1.8.9
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/13.2_generateur_combustion.js +116 -31
- package/13.2_generateur_combustion.spec.js +286 -2
- package/13.2_generateur_combustion_pn.js +248 -0
- package/13.2_generateur_combustion_pn.spec.js +476 -0
- package/README.md +21 -21
- package/conso.js +178 -4
- package/conso.spec.js +187 -1
- package/engine.js +7 -4
- package/package.json +1 -1
- package/utils.js +5 -0
- package/utils.spec.js +53 -0
|
@@ -5,6 +5,7 @@ import { updateGenerateurChaudieres } from './13.2_generateur_combustion_chaudie
|
|
|
5
5
|
import { updateGenerateurPacs } from './13.2_generateur_pac.js';
|
|
6
6
|
import getFicheTechnique from './ficheTechnique.js';
|
|
7
7
|
import { evaluateFormula as evaluateTvFormula } from './formula.js';
|
|
8
|
+
import { conventionPuissanceNominale } from './13.2_generateur_combustion_pn.js';
|
|
8
9
|
|
|
9
10
|
function criterePn(Pn, matcher) {
|
|
10
11
|
let critere_list = tvColumnLines('generateur_combustion', 'critere_pn', matcher);
|
|
@@ -41,6 +42,58 @@ function evaluateFormula(formulaOrValue, pn, E, F) {
|
|
|
41
42
|
return evaluateTvFormula(formulaOrValue, pn, E, F);
|
|
42
43
|
}
|
|
43
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Caractéristiques forfaitaires (rpn, rpint, qp0) d'un générateur à combustion.
|
|
47
|
+
*
|
|
48
|
+
* Si la consommation est obtenue par virtualisation du générateur collectif pour les besoins
|
|
49
|
+
* individuels, les formules sont évaluées sur la puissance du générateur collectif
|
|
50
|
+
* Pn(collectif) = pn / ratio, et qp0 est ramené au logement (× ratio).
|
|
51
|
+
* 17.2.1 - Génération d’un DPE à l’appartement / Traitement des usages collectifs
|
|
52
|
+
*
|
|
53
|
+
* Seules les caractéristiques non saisies (selon la méthode de saisie) sont renvoyées.
|
|
54
|
+
*
|
|
55
|
+
* @param row {object} ligne de la table generateur_combustion
|
|
56
|
+
* @param pn {number} puissance nominale du générateur (W)
|
|
57
|
+
* @param ratio {number} ratio de virtualisation
|
|
58
|
+
* @param E {number}
|
|
59
|
+
* @param F {number}
|
|
60
|
+
* @param type {'ecs'|'ch'}
|
|
61
|
+
* @param methodeSaisie {number}
|
|
62
|
+
* @returns {{rpn?: number, rpint?: number, qp0?: number}}
|
|
63
|
+
*/
|
|
64
|
+
export function caracteristiquesGenerateurCombustion(row, pn, ratio, E, F, type, methodeSaisie) {
|
|
65
|
+
const caracteristiques = {};
|
|
66
|
+
|
|
67
|
+
if (![3, 4, 5].includes(methodeSaisie)) {
|
|
68
|
+
if (row.rpn) {
|
|
69
|
+
caracteristiques.rpn = evaluateFormula(row.rpn, pn / ratio, E, F) / 100;
|
|
70
|
+
}
|
|
71
|
+
if (type === 'ch' && row.rpint) {
|
|
72
|
+
caracteristiques.rpint = evaluateFormula(row.rpint, pn / ratio, E, F) / 100;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (![4, 5].includes(methodeSaisie)) {
|
|
77
|
+
if (row.qp0_perc) {
|
|
78
|
+
const qp0_calc = evaluateFormula(row.qp0_perc, pn / ratio, E, F);
|
|
79
|
+
// Certaines chaudières ont un qp0 en % de pn, d'autres ont des valeurs constantes
|
|
80
|
+
if (row.qp0_perc.includes('Pn')) {
|
|
81
|
+
caracteristiques.qp0 = qp0_calc * 1000 * ratio;
|
|
82
|
+
} else {
|
|
83
|
+
if (row.qp0_perc.includes('%')) {
|
|
84
|
+
caracteristiques.qp0 = qp0_calc * pn;
|
|
85
|
+
} else {
|
|
86
|
+
caracteristiques.qp0 = qp0_calc * 1000 * ratio;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
caracteristiques.qp0 = 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return caracteristiques;
|
|
95
|
+
}
|
|
96
|
+
|
|
44
97
|
/**
|
|
45
98
|
* Si la méthode de saisie n'est pas "Valeur forfaitaire" mais "caractéristiques saisies"
|
|
46
99
|
* Documentation 3CL : "Pour les installations récentes ou recommandées, les caractéristiques réelles des chaudières présentées sur les bases
|
|
@@ -63,6 +116,7 @@ export function tv_generateur_combustion(dpe, di, de, type, GV, tbase, methodeSa
|
|
|
63
116
|
const typeGenerateurKey = `enum_type_generateur_${type}_id`;
|
|
64
117
|
let enumTypeGenerateurId = de[typeGenerateurKey];
|
|
65
118
|
let row;
|
|
119
|
+
let selectionLigne;
|
|
66
120
|
|
|
67
121
|
/**
|
|
68
122
|
* Certains DPE configurent mal les données du générateur ECS lorsque c'est un générateur mixte Chauffage + ECS
|
|
@@ -99,11 +153,14 @@ export function tv_generateur_combustion(dpe, di, de, type, GV, tbase, methodeSa
|
|
|
99
153
|
di.pn = (1.2 * GV * (19 - tbase)) / 0.95 ** 3;
|
|
100
154
|
}
|
|
101
155
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
156
|
+
selectionLigne = (pn, ratio) => {
|
|
157
|
+
let matcher = {};
|
|
158
|
+
matcher[typeGenerateurKey] = enumTypeGenerateurId;
|
|
159
|
+
matcher.critere_pn = criterePn(pn / (ratio * 1000), matcher);
|
|
160
|
+
return tv('generateur_combustion', matcher);
|
|
161
|
+
};
|
|
105
162
|
|
|
106
|
-
row =
|
|
163
|
+
row = selectionLigne(di.pn, de.ratio_virtualisation);
|
|
107
164
|
|
|
108
165
|
/**
|
|
109
166
|
* Si l'identifiant du générateur à combustion utilisé n'est pas le bon, avertissement
|
|
@@ -144,41 +201,69 @@ export function tv_generateur_combustion(dpe, di, de, type, GV, tbase, methodeSa
|
|
|
144
201
|
const E = E_tab[de.presence_ventouse];
|
|
145
202
|
const F = F_tab[de.presence_ventouse];
|
|
146
203
|
|
|
147
|
-
|
|
204
|
+
let ratioVirtualisation = de.ratio_virtualisation || 1;
|
|
148
205
|
|
|
149
206
|
/**
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
207
|
+
* Générateur collectif virtualisé : la puissance saisie dans le DPE peut être la puissance
|
|
208
|
+
* virtualisée Pe = a × Pn (convention 3CL) ou la puissance du générateur collectif Pn selon les
|
|
209
|
+
* logiciels (issue #124). La convention réellement utilisée est déduite des valeurs
|
|
210
|
+
* intermédiaires (rpn, qp0) présentes dans le DPE.
|
|
154
211
|
*/
|
|
155
|
-
if (
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
212
|
+
if (selectionLigne) {
|
|
213
|
+
const ligneOuDefaut = (pn, ratio) => selectionLigne(pn, ratio) || row;
|
|
214
|
+
const caracteristiques = (pn, ratio) =>
|
|
215
|
+
caracteristiquesGenerateurCombustion(
|
|
216
|
+
ligneOuDefaut(pn, ratio),
|
|
217
|
+
pn,
|
|
218
|
+
ratio,
|
|
219
|
+
E,
|
|
220
|
+
F,
|
|
221
|
+
type,
|
|
222
|
+
methodeSaisie
|
|
223
|
+
);
|
|
224
|
+
/**
|
|
225
|
+
* Formule rpn de la ligne sélectionnée pour un Pn(collectif) donné (W) : permet de retrouver
|
|
226
|
+
* Pn(collectif) à partir du rpn stocké (4e hypothèse).
|
|
227
|
+
*/
|
|
228
|
+
const formuleRpn = (pnCollectif) => {
|
|
229
|
+
const ligne = selectionLigne(pnCollectif, 1);
|
|
230
|
+
return ligne?.rpn ? (p) => evaluateFormula(ligne.rpn, p, E, F) / 100 : undefined;
|
|
231
|
+
};
|
|
232
|
+
const puissance = conventionPuissanceNominale(
|
|
233
|
+
di.pn,
|
|
234
|
+
ratioVirtualisation,
|
|
235
|
+
{ rpn: di.rpn, rpint: di.rpint, qp0: di.qp0 },
|
|
236
|
+
caracteristiques,
|
|
237
|
+
bug_for_bug_compat,
|
|
238
|
+
formuleRpn
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
if (puissance.convention === 'puissance_depuis_rpn') {
|
|
242
|
+
console.warn(
|
|
243
|
+
`La puissance nominale du générateur ${de.description} (${di.pn} W) n'est cohérente ni avec la puissance
|
|
244
|
+
virtualisée ni avec celle du générateur collectif. Puissance du générateur collectif recalculée à partir
|
|
245
|
+
du rpn du DPE (${di.rpn}) : Pn = ${puissance.pnCollectif / 1000} kW, utilisation de Pe = a × Pn = ${puissance.pn} W.`
|
|
246
|
+
);
|
|
247
|
+
} else if (puissance.convention !== 'individualisee') {
|
|
248
|
+
console.warn(
|
|
249
|
+
`La puissance nominale du générateur ${de.description} (${di.pn} W) est celle du générateur collectif :
|
|
250
|
+
utilisation de la puissance ${puissance.pn} W et du ratio de virtualisation ${puissance.ratio} (${puissance.convention}).`
|
|
251
|
+
);
|
|
161
252
|
}
|
|
162
|
-
}
|
|
163
253
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
di.qp0 = qp0_calc * 1000 * ratioVirtualisation;
|
|
170
|
-
} else {
|
|
171
|
-
if (row.qp0_perc.includes('%')) {
|
|
172
|
-
di.qp0 = qp0_calc * di.pn;
|
|
173
|
-
} else {
|
|
174
|
-
di.qp0 = qp0_calc * 1000 * ratioVirtualisation;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
} else {
|
|
178
|
-
di.qp0 = 0;
|
|
254
|
+
if (puissance.convention !== 'individualisee') {
|
|
255
|
+
di.pn = puissance.pn;
|
|
256
|
+
ratioVirtualisation = puissance.ratio;
|
|
257
|
+
row = ligneOuDefaut(di.pn, ratioVirtualisation);
|
|
258
|
+
de.tv_generateur_combustion_id = Number(row.tv_generateur_combustion_id);
|
|
179
259
|
}
|
|
180
260
|
}
|
|
181
261
|
|
|
262
|
+
Object.assign(
|
|
263
|
+
di,
|
|
264
|
+
caracteristiquesGenerateurCombustion(row, di.pn, ratioVirtualisation, E, F, type, methodeSaisie)
|
|
265
|
+
);
|
|
266
|
+
|
|
182
267
|
if (methodeSaisie === 1 || !di.pveilleuse) {
|
|
183
268
|
di.pveil = Number(row.pveil) || 0;
|
|
184
269
|
} else {
|
|
@@ -51,10 +51,21 @@ vi.mock('./13.2_generateur_pac.js', () => ({
|
|
|
51
51
|
vi.mock('./ficheTechnique.js', () => ({
|
|
52
52
|
default: vi.fn()
|
|
53
53
|
}));
|
|
54
|
+
/**
|
|
55
|
+
* Détection de la convention de puissance (issue #124) : testée dans son propre spec. Par défaut,
|
|
56
|
+
* le double renvoie la convention individualisée (pn et ratio inchangés).
|
|
57
|
+
*/
|
|
58
|
+
vi.mock('./13.2_generateur_combustion_pn.js', () => ({
|
|
59
|
+
conventionPuissanceNominale: vi.fn((pn, ratio) => ({ pn, ratio, convention: 'individualisee' }))
|
|
60
|
+
}));
|
|
54
61
|
|
|
55
|
-
const {
|
|
56
|
-
|
|
62
|
+
const {
|
|
63
|
+
tv_generateur_combustion,
|
|
64
|
+
updateGenerateurCombustion,
|
|
65
|
+
caracteristiquesGenerateurCombustion
|
|
66
|
+
} = await import('./13.2_generateur_combustion.js');
|
|
57
67
|
const { tv, tvColumnLines } = await import('./utils.js');
|
|
68
|
+
const { conventionPuissanceNominale } = await import('./13.2_generateur_combustion_pn.js');
|
|
58
69
|
const { updateGenerateurBouilleurs } = await import('./13.2_generateur_combustion_bouilleur.js');
|
|
59
70
|
const { updateGenerateurChaudieres } = await import('./13.2_generateur_combustion_chaudiere.js');
|
|
60
71
|
const { updateGenerateurPacs } = await import('./13.2_generateur_pac.js');
|
|
@@ -68,6 +79,12 @@ beforeEach(() => {
|
|
|
68
79
|
vi.mocked(updateGenerateurChaudieres).mockReset();
|
|
69
80
|
vi.mocked(updateGenerateurPacs).mockReset();
|
|
70
81
|
vi.mocked(getFicheTechnique).mockReset();
|
|
82
|
+
vi.mocked(conventionPuissanceNominale).mockReset();
|
|
83
|
+
vi.mocked(conventionPuissanceNominale).mockImplementation((pn, ratio) => ({
|
|
84
|
+
pn,
|
|
85
|
+
ratio,
|
|
86
|
+
convention: 'individualisee'
|
|
87
|
+
}));
|
|
71
88
|
state.bug = false;
|
|
72
89
|
});
|
|
73
90
|
|
|
@@ -535,3 +552,270 @@ describe('updateGenerateurCombustion - orchestration des substitutions', () => {
|
|
|
535
552
|
expect(de.presenceVentilateur).toBeUndefined();
|
|
536
553
|
});
|
|
537
554
|
});
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Issue #124 : générateur collectif virtualisé, puissance saisie collective (Pn) ou individualisée
|
|
558
|
+
* (Pe = a × Pn) selon les logiciels.
|
|
559
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2 et §17.2.1
|
|
560
|
+
*/
|
|
561
|
+
describe('tv_generateur_combustion - convention de puissance d’un générateur virtualisé (#124)', () => {
|
|
562
|
+
const ROW_PN = {
|
|
563
|
+
tv_generateur_combustion_id: '42',
|
|
564
|
+
rpn: '84 + 2 logPn',
|
|
565
|
+
rpint: '80 + 3 logPn',
|
|
566
|
+
qp0_perc: '1%',
|
|
567
|
+
pveil: '0'
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
test('la détection reçoit pn, ratio, valeurs du DPE et bug_for_bug_compat', () => {
|
|
571
|
+
state.bug = true;
|
|
572
|
+
tv.mockReturnValue({ ...ROW_PN });
|
|
573
|
+
const di = { pn: 23000, rpn: 0.87, qp0: 0.276 };
|
|
574
|
+
const de = {
|
|
575
|
+
enum_type_generateur_ch_id: '89',
|
|
576
|
+
ratio_virtualisation: 0.1,
|
|
577
|
+
presence_ventouse: 0
|
|
578
|
+
};
|
|
579
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
580
|
+
expect(conventionPuissanceNominale).toHaveBeenCalledWith(
|
|
581
|
+
23000,
|
|
582
|
+
0.1,
|
|
583
|
+
{ rpn: 0.87, rpint: undefined, qp0: 0.276 },
|
|
584
|
+
expect.any(Function),
|
|
585
|
+
true,
|
|
586
|
+
expect.any(Function)
|
|
587
|
+
);
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
test('formule rpn fournie (4e hypothèse) : ligne sélectionnée sur Pn collectif, rpn en fraction', () => {
|
|
591
|
+
tvColumnLines.mockReturnValue(['Pn ≤ 70', 'Pn > 70']);
|
|
592
|
+
tv.mockReturnValue({ ...ROW_PN });
|
|
593
|
+
let formuleRpn;
|
|
594
|
+
conventionPuissanceNominale.mockImplementation((pn, ratio, _, __, ___, fn) => {
|
|
595
|
+
formuleRpn = fn;
|
|
596
|
+
return { pn, ratio, convention: 'individualisee' };
|
|
597
|
+
});
|
|
598
|
+
const di = { pn: 23000, rpint: 0.85 };
|
|
599
|
+
const de = {
|
|
600
|
+
enum_type_generateur_ch_id: '89',
|
|
601
|
+
ratio_virtualisation: 0.1,
|
|
602
|
+
presence_ventouse: 0
|
|
603
|
+
};
|
|
604
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
605
|
+
expect(conventionPuissanceNominale.mock.calls[0][2]).toEqual({
|
|
606
|
+
rpn: undefined,
|
|
607
|
+
rpint: 0.85,
|
|
608
|
+
qp0: undefined
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
tv.mockClear();
|
|
612
|
+
const formule = formuleRpn(696000);
|
|
613
|
+
// Pn collectif = 696 kW (ratio 1) -> critère « Pn > 70 »
|
|
614
|
+
expect(tv).toHaveBeenCalledWith(
|
|
615
|
+
'generateur_combustion',
|
|
616
|
+
expect.objectContaining({ critere_pn: 'Pn > 70' })
|
|
617
|
+
);
|
|
618
|
+
// Référence de régression : rpn = (84 + 2 log10(696)) / 100
|
|
619
|
+
expect(formule(696000)).toBeCloseTo((84 + 2 * Math.log10(696)) / 100, 9);
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
test('formule rpn : ligne absente ou sans rpn -> aucune formule', () => {
|
|
623
|
+
tv.mockReturnValueOnce({ ...ROW_PN });
|
|
624
|
+
let formuleRpn;
|
|
625
|
+
conventionPuissanceNominale.mockImplementation((pn, ratio, _, __, ___, fn) => {
|
|
626
|
+
formuleRpn = fn;
|
|
627
|
+
return { pn, ratio, convention: 'individualisee' };
|
|
628
|
+
});
|
|
629
|
+
const de = {
|
|
630
|
+
enum_type_generateur_ch_id: '89',
|
|
631
|
+
ratio_virtualisation: 0.1,
|
|
632
|
+
presence_ventouse: 0
|
|
633
|
+
};
|
|
634
|
+
tv_generateur_combustion({}, { pn: 23000 }, de, 'ch', 200, -9, 1);
|
|
635
|
+
tv.mockReturnValueOnce(null).mockReturnValueOnce({ ...ROW_PN, rpn: undefined });
|
|
636
|
+
expect(formuleRpn(696000)).toBeUndefined();
|
|
637
|
+
expect(formuleRpn(696000)).toBeUndefined();
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
test('pn recalculé depuis rpn : Pe retenu, ligne re-sélectionnée et avertissement explicite', () => {
|
|
641
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
642
|
+
tv.mockReturnValueOnce({ ...ROW_PN }).mockReturnValue({
|
|
643
|
+
...ROW_PN,
|
|
644
|
+
tv_generateur_combustion_id: '43'
|
|
645
|
+
});
|
|
646
|
+
conventionPuissanceNominale.mockReturnValue({
|
|
647
|
+
pn: 2300,
|
|
648
|
+
ratio: 0.1,
|
|
649
|
+
convention: 'puissance_depuis_rpn',
|
|
650
|
+
pnCollectif: 23000
|
|
651
|
+
});
|
|
652
|
+
const di = { pn: 230, rpn: 0.8672, rpint: 0.8408 };
|
|
653
|
+
const de = {
|
|
654
|
+
description: 'Chaudière collective',
|
|
655
|
+
enum_type_generateur_ch_id: '89',
|
|
656
|
+
ratio_virtualisation: 0.1,
|
|
657
|
+
presence_ventouse: 0
|
|
658
|
+
};
|
|
659
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
660
|
+
expect(di.pn).toBe(2300);
|
|
661
|
+
expect(de.tv_generateur_combustion_id).toBe(43);
|
|
662
|
+
// Formules évaluées sur Pn collectif = 2300 / 0.1 = 23 kW
|
|
663
|
+
expect(di.rpn).toBeCloseTo((84 + 2 * Math.log10(23)) / 100, 9);
|
|
664
|
+
const message = warnSpy.mock.calls[0][0];
|
|
665
|
+
expect(message).toContain('(230 W)');
|
|
666
|
+
expect(message).toContain('Pn = 23 kW');
|
|
667
|
+
expect(message).toContain('Pe = a × Pn = 2300 W');
|
|
668
|
+
warnSpy.mockRestore();
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
test('fonction de caractéristiques fournie : ligne et formules évaluées sur pn / ratio', () => {
|
|
672
|
+
tvColumnLines.mockReturnValue(['Pn ≤ 70', 'Pn > 70']);
|
|
673
|
+
tv.mockReturnValue({ ...ROW_PN });
|
|
674
|
+
let caracteristiques;
|
|
675
|
+
conventionPuissanceNominale.mockImplementation((pn, ratio, _, fn) => {
|
|
676
|
+
caracteristiques = fn;
|
|
677
|
+
return { pn, ratio, convention: 'individualisee' };
|
|
678
|
+
});
|
|
679
|
+
const di = { pn: 23000 };
|
|
680
|
+
const de = {
|
|
681
|
+
enum_type_generateur_ch_id: '89',
|
|
682
|
+
ratio_virtualisation: 0.1,
|
|
683
|
+
presence_ventouse: 0
|
|
684
|
+
};
|
|
685
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
686
|
+
|
|
687
|
+
tv.mockClear();
|
|
688
|
+
const hypothese = caracteristiques(2300, 0.1);
|
|
689
|
+
// Pn collectif = 2300 / 0.1 = 23 kW -> critère « Pn ≤ 70 »
|
|
690
|
+
expect(tv).toHaveBeenCalledWith(
|
|
691
|
+
'generateur_combustion',
|
|
692
|
+
expect.objectContaining({ critere_pn: 'Pn ≤ 70' })
|
|
693
|
+
);
|
|
694
|
+
// Référence de régression : rpn = (84 + 2 log10(23)) / 100
|
|
695
|
+
expect(hypothese.rpn).toBeCloseTo((84 + 2 * Math.log10(23)) / 100, 9);
|
|
696
|
+
// qp0 en % : rapporté à la puissance saisie (2300 W)
|
|
697
|
+
expect(hypothese.qp0).toBeCloseTo(23, 9);
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
test('aucune ligne pour l’hypothèse testée : repli sur la ligne initiale', () => {
|
|
701
|
+
tv.mockReturnValueOnce({ ...ROW_PN }).mockReturnValue(null);
|
|
702
|
+
let caracteristiques;
|
|
703
|
+
conventionPuissanceNominale.mockImplementation((pn, ratio, _, fn) => {
|
|
704
|
+
caracteristiques = fn;
|
|
705
|
+
return { pn, ratio, convention: 'individualisee' };
|
|
706
|
+
});
|
|
707
|
+
const di = { pn: 23000 };
|
|
708
|
+
const de = {
|
|
709
|
+
enum_type_generateur_ch_id: '89',
|
|
710
|
+
ratio_virtualisation: 0.1,
|
|
711
|
+
presence_ventouse: 0
|
|
712
|
+
};
|
|
713
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
714
|
+
expect(caracteristiques(23000, 1).rpn).toBeCloseTo((84 + 2 * Math.log10(23)) / 100, 9);
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
test('convention individualisée : pn, ratio et identifiant inchangés', () => {
|
|
718
|
+
tv.mockReturnValue({ ...ROW_PN });
|
|
719
|
+
const di = { pn: 23000 };
|
|
720
|
+
const de = {
|
|
721
|
+
enum_type_generateur_ch_id: '89',
|
|
722
|
+
ratio_virtualisation: 0.1,
|
|
723
|
+
presence_ventouse: 0
|
|
724
|
+
};
|
|
725
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
726
|
+
expect(di.pn).toBe(23000);
|
|
727
|
+
// rpn évalué sur Pn collectif = 230 kW
|
|
728
|
+
expect(di.rpn).toBeCloseTo((84 + 2 * Math.log10(230)) / 100, 9);
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
test('puissance collective virtualisée : pn ramené à Pe, ligne et identifiant re-sélectionnés', () => {
|
|
732
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
733
|
+
tv.mockReturnValueOnce({ ...ROW_PN }).mockReturnValue({
|
|
734
|
+
...ROW_PN,
|
|
735
|
+
tv_generateur_combustion_id: '43'
|
|
736
|
+
});
|
|
737
|
+
conventionPuissanceNominale.mockReturnValue({
|
|
738
|
+
pn: 2300,
|
|
739
|
+
ratio: 0.1,
|
|
740
|
+
convention: 'collective_virtualisee'
|
|
741
|
+
});
|
|
742
|
+
const di = { pn: 23000, rpn: 0.9, qp0: 23 };
|
|
743
|
+
const de = {
|
|
744
|
+
enum_type_generateur_ch_id: '89',
|
|
745
|
+
ratio_virtualisation: 0.1,
|
|
746
|
+
presence_ventouse: 0
|
|
747
|
+
};
|
|
748
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
749
|
+
expect(di.pn).toBe(2300);
|
|
750
|
+
expect(de.tv_generateur_combustion_id).toBe(43);
|
|
751
|
+
// Formules évaluées sur Pn collectif = 2300 / 0.1 = 23 kW
|
|
752
|
+
expect(di.rpn).toBeCloseTo((84 + 2 * Math.log10(23)) / 100, 9);
|
|
753
|
+
expect(di.rpint).toBeCloseTo((80 + 3 * Math.log10(23)) / 100, 9);
|
|
754
|
+
expect(di.qp0).toBeCloseTo(23, 9);
|
|
755
|
+
expect(warnSpy).toHaveBeenCalled();
|
|
756
|
+
warnSpy.mockRestore();
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
test('puissance collective non virtualisée (bug_for_bug_compat) : calcul sur pn avec ratio 1', () => {
|
|
760
|
+
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
761
|
+
state.bug = true;
|
|
762
|
+
tv.mockReturnValue({ ...ROW_PN });
|
|
763
|
+
conventionPuissanceNominale.mockReturnValue({
|
|
764
|
+
pn: 23000,
|
|
765
|
+
ratio: 1,
|
|
766
|
+
convention: 'collective_non_virtualisee'
|
|
767
|
+
});
|
|
768
|
+
const di = { pn: 23000, rpn: 0.87, qp0: 0.23 };
|
|
769
|
+
const de = {
|
|
770
|
+
enum_type_generateur_ch_id: '89',
|
|
771
|
+
ratio_virtualisation: 0.1,
|
|
772
|
+
presence_ventouse: 0
|
|
773
|
+
};
|
|
774
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
775
|
+
expect(di.pn).toBe(23000);
|
|
776
|
+
expect(di.rpn).toBeCloseTo((84 + 2 * Math.log10(23)) / 100, 9);
|
|
777
|
+
expect(di.qp0).toBeCloseTo(230, 9);
|
|
778
|
+
warnSpy.mockRestore();
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
test('générateur collectif par défaut (119, tv_generateur_combustion_id) : pas de détection', () => {
|
|
782
|
+
state.bug = true;
|
|
783
|
+
tv.mockReturnValue({ ...ROW_PN });
|
|
784
|
+
const di = { pn: 23000 };
|
|
785
|
+
const de = {
|
|
786
|
+
enum_type_generateur_ch_id: '119',
|
|
787
|
+
tv_generateur_combustion_id: '42',
|
|
788
|
+
ratio_virtualisation: 0.1,
|
|
789
|
+
presence_ventouse: 0
|
|
790
|
+
};
|
|
791
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
792
|
+
expect(conventionPuissanceNominale).not.toHaveBeenCalled();
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
describe('caracteristiquesGenerateurCombustion - selon la méthode de saisie', () => {
|
|
797
|
+
const ROW = { rpn: '84 + 2 logPn', rpint: '80 + 3 logPn', qp0_perc: '1%' };
|
|
798
|
+
|
|
799
|
+
test('méthode forfaitaire : rpn, rpint et qp0 calculés', () => {
|
|
800
|
+
expect(
|
|
801
|
+
Object.keys(caracteristiquesGenerateurCombustion(ROW, 23000, 1, 2.5, -0.8, 'ch', 1))
|
|
802
|
+
).toEqual(['rpn', 'rpint', 'qp0']);
|
|
803
|
+
});
|
|
804
|
+
|
|
805
|
+
test('méthode 3 : rpn et rpint saisis, seul qp0 calculé', () => {
|
|
806
|
+
expect(caracteristiquesGenerateurCombustion(ROW, 23000, 1, 2.5, -0.8, 'ch', 3)).toEqual({
|
|
807
|
+
qp0: expect.any(Number)
|
|
808
|
+
});
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
test('méthodes 4 et 5 : aucune caractéristique calculée', () => {
|
|
812
|
+
expect(caracteristiquesGenerateurCombustion(ROW, 23000, 1, 2.5, -0.8, 'ch', 4)).toEqual({});
|
|
813
|
+
expect(caracteristiquesGenerateurCombustion(ROW, 23000, 1, 2.5, -0.8, 'ch', 5)).toEqual({});
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
test('qp0 constant en kW (sans % ni Pn) : ramené au logement par le ratio', () => {
|
|
817
|
+
expect(
|
|
818
|
+
caracteristiquesGenerateurCombustion({ qp0_perc: '0.5' }, 2300, 0.1, 2.5, -0.8, 'ecs', 1).qp0
|
|
819
|
+
).toBeCloseTo(50, 9);
|
|
820
|
+
});
|
|
821
|
+
});
|