@open3cl/engine 1.8.45 → 1.8.47
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 +22 -5
- package/13.2_generateur_combustion.spec.js +102 -0
- package/README.md +21 -21
- package/conso.js +113 -18
- package/conso.spec.js +85 -0
- package/engine.js +3 -1
- package/package.json +1 -1
|
@@ -256,8 +256,18 @@ export function tv_generateur_combustion(dpe, di, de, type, GV, tbase, methodeSa
|
|
|
256
256
|
|
|
257
257
|
de.tv_generateur_combustion_id = Number(row.tv_generateur_combustion_id);
|
|
258
258
|
|
|
259
|
-
|
|
260
|
-
|
|
259
|
+
/**
|
|
260
|
+
* Les coefficients (E, F) dépendent de la présence d'un ventilateur ou autre dispositif de
|
|
261
|
+
* circulation d'air dans le circuit de combustion, et non de la ventouse (qui n'intervient que
|
|
262
|
+
* dans Cper). Le XML ne transporte pas cette donnée : elle est lue dans la fiche technique du
|
|
263
|
+
* générateur. Sans fiche technique, la ventouse est conservée comme approximation (choix
|
|
264
|
+
* Open3CL, la méthode ne prévoyant pas de valeur par défaut).
|
|
265
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
|
|
266
|
+
* @see : Tribu Calcul_generateur.cs (ventilateur_combustion)
|
|
267
|
+
*/
|
|
268
|
+
const indexEF = de.ventilateurCombustion ?? de.presence_ventouse;
|
|
269
|
+
const E = E_tab[indexEF];
|
|
270
|
+
const F = F_tab[indexEF];
|
|
261
271
|
|
|
262
272
|
let ratioVirtualisation = de.ratio_virtualisation || 1;
|
|
263
273
|
|
|
@@ -341,7 +351,7 @@ export function updateGenerateurCombustion(dpe, de, type) {
|
|
|
341
351
|
updateGenerateurBouilleurs(dpe, de, type);
|
|
342
352
|
updateGenerateurChaudieres(dpe, de, type);
|
|
343
353
|
updateGenerateurPacs(dpe, de, type);
|
|
344
|
-
addInfosFromFichesTechniques(dpe, de);
|
|
354
|
+
addInfosFromFichesTechniques(dpe, de, type);
|
|
345
355
|
}
|
|
346
356
|
|
|
347
357
|
/**
|
|
@@ -349,12 +359,14 @@ export function updateGenerateurCombustion(dpe, de, type) {
|
|
|
349
359
|
*
|
|
350
360
|
* @param dpe {FullDpe}
|
|
351
361
|
* @param de {Donnee_entree}
|
|
362
|
+
* @param type {'ch'|'ecs'}
|
|
352
363
|
*/
|
|
353
|
-
function addInfosFromFichesTechniques(dpe, de) {
|
|
364
|
+
function addInfosFromFichesTechniques(dpe, de, type) {
|
|
354
365
|
// Récupération de la présence ou non d'un système de ventilation
|
|
366
|
+
// Fiches techniques : catégorie 7 pour le chauffage, catégorie 8 pour l'ECS
|
|
355
367
|
const ficheTechnique = getFicheTechnique(
|
|
356
368
|
dpe,
|
|
357
|
-
'8',
|
|
369
|
+
type === 'ch' ? '7' : '8',
|
|
358
370
|
'Présence ventilateur / dispositif circulation air dans circuit combustion',
|
|
359
371
|
[de.description]
|
|
360
372
|
)?.valeur;
|
|
@@ -362,6 +374,11 @@ function addInfosFromFichesTechniques(dpe, de) {
|
|
|
362
374
|
if (ficheTechnique && ficheTechnique === 'oui') {
|
|
363
375
|
de.presenceVentilateur = 1;
|
|
364
376
|
}
|
|
377
|
+
|
|
378
|
+
// Présence d'un ventilateur dans le circuit de combustion (choix des coefficients E, F de qp0)
|
|
379
|
+
if (ficheTechnique === 'oui' || ficheTechnique === 'non') {
|
|
380
|
+
de.ventilateurCombustion = ficheTechnique === 'oui' ? 1 : 0;
|
|
381
|
+
}
|
|
365
382
|
}
|
|
366
383
|
|
|
367
384
|
/**
|
|
@@ -833,6 +833,108 @@ describe('updateGenerateurCombustion - orchestration des substitutions', () => {
|
|
|
833
833
|
updateGenerateurCombustion({}, de, 'ch');
|
|
834
834
|
expect(de.presenceVentilateur).toBeUndefined();
|
|
835
835
|
});
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Issue #35 : la fiche technique d'un générateur de chauffage est en catégorie 7, celle d'un
|
|
839
|
+
* générateur ECS en catégorie 8.
|
|
840
|
+
*/
|
|
841
|
+
test('générateur de chauffage : fiche technique recherchée en catégorie 7 (#35)', () => {
|
|
842
|
+
getFicheTechnique.mockReturnValue(undefined);
|
|
843
|
+
const dpe = {};
|
|
844
|
+
updateGenerateurCombustion(dpe, { description: 'chaudière' }, 'ch');
|
|
845
|
+
expect(getFicheTechnique).toHaveBeenCalledWith(
|
|
846
|
+
dpe,
|
|
847
|
+
'7',
|
|
848
|
+
'Présence ventilateur / dispositif circulation air dans circuit combustion',
|
|
849
|
+
['chaudière']
|
|
850
|
+
);
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
test('générateur ECS : fiche technique recherchée en catégorie 8 (#35)', () => {
|
|
854
|
+
getFicheTechnique.mockReturnValue(undefined);
|
|
855
|
+
const dpe = {};
|
|
856
|
+
updateGenerateurCombustion(dpe, { description: 'chauffe-eau' }, 'ecs');
|
|
857
|
+
expect(getFicheTechnique).toHaveBeenCalledWith(
|
|
858
|
+
dpe,
|
|
859
|
+
'8',
|
|
860
|
+
'Présence ventilateur / dispositif circulation air dans circuit combustion',
|
|
861
|
+
['chauffe-eau']
|
|
862
|
+
);
|
|
863
|
+
});
|
|
864
|
+
|
|
865
|
+
test('ventilateur de combustion renseigné à 1 si la fiche indique « oui » (#35)', () => {
|
|
866
|
+
getFicheTechnique.mockReturnValue({ valeur: 'oui' });
|
|
867
|
+
const de = { description: 'gen' };
|
|
868
|
+
updateGenerateurCombustion({}, de, 'ch');
|
|
869
|
+
expect(de.ventilateurCombustion).toBe(1);
|
|
870
|
+
});
|
|
871
|
+
|
|
872
|
+
test('ventilateur de combustion renseigné à 0 si la fiche indique « non » (#35)', () => {
|
|
873
|
+
getFicheTechnique.mockReturnValue({ valeur: 'non' });
|
|
874
|
+
const de = { description: 'gen' };
|
|
875
|
+
updateGenerateurCombustion({}, de, 'ch');
|
|
876
|
+
expect(de.ventilateurCombustion).toBe(0);
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
test('ventilateur de combustion non renseigné sans fiche ou valeur inconnue (#35)', () => {
|
|
880
|
+
getFicheTechnique.mockReturnValue(undefined);
|
|
881
|
+
const deSansFiche = { description: 'gen' };
|
|
882
|
+
updateGenerateurCombustion({}, deSansFiche, 'ch');
|
|
883
|
+
expect(deSansFiche.ventilateurCombustion).toBeUndefined();
|
|
884
|
+
|
|
885
|
+
getFicheTechnique.mockReturnValue({ valeur: 'inconnu' });
|
|
886
|
+
const deInconnu = { description: 'gen' };
|
|
887
|
+
updateGenerateurCombustion({}, deInconnu, 'ch');
|
|
888
|
+
expect(deInconnu.ventilateurCombustion).toBeUndefined();
|
|
889
|
+
});
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Issue #35 : les coefficients (E, F) de la formule qp0 dépendent de la présence d'un ventilateur
|
|
894
|
+
* dans le circuit de combustion (fiche technique), la ventouse n'étant qu'un repli.
|
|
895
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
|
|
896
|
+
*/
|
|
897
|
+
describe('tv_generateur_combustion - coefficients (E, F) selon le ventilateur de combustion (#35)', () => {
|
|
898
|
+
const ROW_EF = { ...ROW_DEFAUT, rpn: 'E*40', qp0_perc: 'Pn*(E+F*log10(Pn))/100' };
|
|
899
|
+
|
|
900
|
+
test('ventouse mais pas de ventilateur : couple (E, F) sans ventilateur (2,5 ; -0,8)', () => {
|
|
901
|
+
tv.mockReturnValue({ ...ROW_EF });
|
|
902
|
+
const di = { pn: 24000 };
|
|
903
|
+
const de = {
|
|
904
|
+
enum_type_generateur_ch_id: '93',
|
|
905
|
+
ratio_virtualisation: 1,
|
|
906
|
+
presence_ventouse: 1,
|
|
907
|
+
ventilateurCombustion: 0
|
|
908
|
+
};
|
|
909
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
910
|
+
// E = 2.5 => rpn = 2.5*40/100 = 1
|
|
911
|
+
expect(di.rpn).toBeCloseTo(1, 9);
|
|
912
|
+
// qp0 = 24000 * (2.5 - 0.8 * log10(24)) / 100 -- valeur du DPE 2459E3195669T
|
|
913
|
+
expect(di.qp0).toBeCloseTo(334.99944159137164, 9);
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
test('ventilateur sans ventouse : couple (E, F) avec ventilateur (1,75 ; -0,55)', () => {
|
|
917
|
+
tv.mockReturnValue({ ...ROW_EF });
|
|
918
|
+
const di = { pn: 24000 };
|
|
919
|
+
const de = {
|
|
920
|
+
enum_type_generateur_ch_id: '93',
|
|
921
|
+
ratio_virtualisation: 1,
|
|
922
|
+
presence_ventouse: 0,
|
|
923
|
+
ventilateurCombustion: 1
|
|
924
|
+
};
|
|
925
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
926
|
+
expect(di.rpn).toBeCloseTo(0.7, 9);
|
|
927
|
+
// qp0 = 24000 * (1.75 - 0.55 * log10(24)) / 100 -- valeur de référence de régression
|
|
928
|
+
expect(di.qp0).toBeCloseTo(237.81211609406802, 9);
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
test('sans information de ventilateur : repli sur la présence de ventouse', () => {
|
|
932
|
+
tv.mockReturnValue({ ...ROW_EF });
|
|
933
|
+
const di = { pn: 24000 };
|
|
934
|
+
const de = { enum_type_generateur_ch_id: '93', ratio_virtualisation: 1, presence_ventouse: 1 };
|
|
935
|
+
tv_generateur_combustion({}, di, de, 'ch', 200, -9, 1);
|
|
936
|
+
expect(di.qp0).toBeCloseTo(237.81211609406802, 9);
|
|
937
|
+
});
|
|
836
938
|
});
|
|
837
939
|
|
|
838
940
|
/**
|
package/README.md
CHANGED
|
@@ -370,29 +370,29 @@ Ces résultats sont **générés automatiquement** à la fin de `npm run test:co
|
|
|
370
370
|
|
|
371
371
|
<!-- CORPUS:START -->
|
|
372
372
|
|
|
373
|
-
> **Version `1.8.
|
|
373
|
+
> **Version `1.8.46`** · branche `main` · généré le 2026-10-11
|
|
374
374
|
> Seuil de tolérance **5%**
|
|
375
375
|
|
|
376
376
|
<table>
|
|
377
377
|
<tr>
|
|
378
378
|
<td align="center"><strong>9</strong><br/><sub>corpus</sub></td>
|
|
379
379
|
<td align="center"><strong>89 984</strong><br/><sub>DPE analysés</sub></td>
|
|
380
|
-
<td align="center"><strong>
|
|
381
|
-
<td align="center"><strong>
|
|
380
|
+
<td align="center"><strong>62 119</strong><br/><sub>DPE conformes</sub></td>
|
|
381
|
+
<td align="center"><strong>69,03 %</strong><br/><sub>réussite globale</sub></td>
|
|
382
382
|
</tr>
|
|
383
383
|
</table>
|
|
384
384
|
|
|
385
385
|
| | Corpus | Réussite | | DPE conformes |
|
|
386
386
|
| :-: | :---------------------------------------------------------------------------------------------------------------------- | ----------: | :--------------------- | -------------: |
|
|
387
|
-
| 🔴 | **Généraliste**<br/><sub>`corpus_dpe.csv`</sub> | **46,
|
|
387
|
+
| 🔴 | **Généraliste**<br/><sub>`corpus_dpe.csv`</sub> | **46,42 %** | `█████████░░░░░░░░░░░` | 4 642 / 9 999 |
|
|
388
388
|
| 🟢 | **Appartement · chauffage individuel (2025)**<br/><sub>`dpe_appartement_individuel_chauffage_individuel_2025.csv`</sub> | **92,56 %** | `███████████████████░` | 9 256 / 10 000 |
|
|
389
|
-
| 🟢 | **Logement individuel (2025)**<br/><sub>`dpe_logement_individuel_2025.csv`</sub> | **89,
|
|
389
|
+
| 🟢 | **Logement individuel (2025)**<br/><sub>`dpe_logement_individuel_2025.csv`</sub> | **89,71 %** | `██████████████████░░` | 8 964 / 9 992 |
|
|
390
390
|
| 🟢 | **Maison individuelle (2025)**<br/><sub>`dpe_maison_individuelle_2025.csv`</sub> | **88,66 %** | `██████████████████░░` | 8 865 / 9 999 |
|
|
391
391
|
| 🟡 | **Immeuble · chauffage individuel**<br/><sub>`dpe_immeuble_chauffage_individuel.csv`</sub> | **84,23 %** | `█████████████████░░░` | 8 421 / 9 998 |
|
|
392
392
|
| 🟡 | **Appartement · chauffage collectif (2025)**<br/><sub>`dpe_appartement_individuel_chauffage_collectif_2025.csv`</sub> | **71,70 %** | `██████████████░░░░░░` | 7 170 / 10 000 |
|
|
393
|
-
| 🟡 | **Immeuble · chauffage collectif**<br/><sub>`dpe_immeuble_chauffage_collectif.csv`</sub> | **66,
|
|
394
|
-
| 🔴 | **Immeuble · chauffage mixte**<br/><sub>`dpe_immeuble_chauffage_mixte.csv`</sub> | **
|
|
395
|
-
| 🔴 | **Individuel généré depuis l'immeuble (2026)**<br/><sub>`dpe_individuel_a_partir_dpe_immeuble_2026.csv`</sub> | **27,
|
|
393
|
+
| 🟡 | **Immeuble · chauffage collectif**<br/><sub>`dpe_immeuble_chauffage_collectif.csv`</sub> | **66,40 %** | `█████████████░░░░░░░` | 6 639 / 9 999 |
|
|
394
|
+
| 🔴 | **Immeuble · chauffage mixte**<br/><sub>`dpe_immeuble_chauffage_mixte.csv`</sub> | **54,14 %** | `███████████░░░░░░░░░` | 5 412 / 9 997 |
|
|
395
|
+
| 🔴 | **Individuel généré depuis l'immeuble (2026)**<br/><sub>`dpe_individuel_a_partir_dpe_immeuble_2026.csv`</sub> | **27,50 %** | `██████░░░░░░░░░░░░░░` | 2 750 / 10 000 |
|
|
396
396
|
|
|
397
397
|
<sub>🟢 ≥ 85 % · 🟡 ≥ 60 % · 🔴 < 60 %</sub>
|
|
398
398
|
|
|
@@ -403,24 +403,24 @@ Ces résultats sont **générés automatiquement** à la fin de `npm run test:co
|
|
|
403
403
|
|
|
404
404
|
<table>
|
|
405
405
|
<tr>
|
|
406
|
-
<td align="center"><strong>5,
|
|
407
|
-
<td align="center"><strong>
|
|
408
|
-
<td align="center"><strong>0,
|
|
409
|
-
<td align="center"><strong>
|
|
406
|
+
<td align="center"><strong>5,63 ms</strong><br/><sub>moyenne</sub></td>
|
|
407
|
+
<td align="center"><strong>5,00 ms</strong><br/><sub>médiane</sub></td>
|
|
408
|
+
<td align="center"><strong>0,14 ms</strong><br/><sub>min</sub></td>
|
|
409
|
+
<td align="center"><strong>601,2 ms</strong><br/><sub>max</sub></td>
|
|
410
410
|
</tr>
|
|
411
411
|
</table>
|
|
412
412
|
|
|
413
413
|
| Corpus | Moyenne | Médiane | Min | Max | p95 | p99 |
|
|
414
414
|
| :--------------------------------------------- | ------: | ------: | ------: | -------: | ------: | ------: |
|
|
415
|
-
| **Généraliste** |
|
|
416
|
-
| **Appartement · chauffage individuel (2025)** |
|
|
417
|
-
| **Logement individuel (2025)** |
|
|
418
|
-
| **Maison individuelle (2025)** |
|
|
419
|
-
| **Immeuble · chauffage individuel** | 6,
|
|
420
|
-
| **Appartement · chauffage collectif (2025)** |
|
|
421
|
-
| **Immeuble · chauffage collectif** |
|
|
422
|
-
| **Immeuble · chauffage mixte** | 5,
|
|
423
|
-
| **Individuel généré depuis l'immeuble (2026)** |
|
|
415
|
+
| **Généraliste** | 5,37 ms | 4,86 ms | 0,26 ms | 97,3 ms | 9,51 ms | 14,0 ms |
|
|
416
|
+
| **Appartement · chauffage individuel (2025)** | 4,70 ms | 4,36 ms | 1,56 ms | 36,9 ms | 7,96 ms | 11,1 ms |
|
|
417
|
+
| **Logement individuel (2025)** | 4,99 ms | 4,45 ms | 1,68 ms | 43,5 ms | 9,03 ms | 12,5 ms |
|
|
418
|
+
| **Maison individuelle (2025)** | 6,20 ms | 5,63 ms | 1,90 ms | 54,9 ms | 10,8 ms | 14,3 ms |
|
|
419
|
+
| **Immeuble · chauffage individuel** | 6,48 ms | 5,52 ms | 0,14 ms | 89,1 ms | 13,0 ms | 21,1 ms |
|
|
420
|
+
| **Appartement · chauffage collectif (2025)** | 5,12 ms | 4,90 ms | 1,79 ms | 42,1 ms | 8,10 ms | 12,6 ms |
|
|
421
|
+
| **Immeuble · chauffage collectif** | 6,73 ms | 5,99 ms | 0,20 ms | 171,0 ms | 12,4 ms | 21,7 ms |
|
|
422
|
+
| **Immeuble · chauffage mixte** | 5,17 ms | 4,24 ms | 0,19 ms | 601,2 ms | 10,5 ms | 16,5 ms |
|
|
423
|
+
| **Individuel généré depuis l'immeuble (2026)** | 5,87 ms | 5,04 ms | 1,69 ms | 48,6 ms | 11,0 ms | 16,6 ms |
|
|
424
424
|
|
|
425
425
|
<sub>La moyenne est tirée vers le haut par les DPE collectifs, dont le coût atteint plusieurs
|
|
426
426
|
dizaines de fois la médiane : c’est la médiane qui décrit le cas courant, et p95/p99 le cas
|
package/conso.js
CHANGED
|
@@ -582,47 +582,142 @@ export default function calc_conso(
|
|
|
582
582
|
ret.sortie_par_energie_collection = {};
|
|
583
583
|
ret.sortie_par_energie_collection.sortie_par_energie = energie_ids.reduce((acc, energie_id) => {
|
|
584
584
|
const type_energie = enums.type_energie[energie_id];
|
|
585
|
-
let vt_en, fr_en;
|
|
586
|
-
if (type_energie === 'électricité') {
|
|
587
|
-
vt_en = vt;
|
|
588
|
-
fr_en = fr;
|
|
589
|
-
} else {
|
|
590
|
-
vt_en = [];
|
|
591
|
-
fr_en = [];
|
|
592
|
-
}
|
|
593
585
|
const gen_ch_en = gen_ch.filter(
|
|
594
586
|
(gen_ch) => gen_ch.donnee_entree.enum_type_energie_id === energie_id
|
|
595
587
|
);
|
|
596
588
|
const gen_ecs_en = gen_ecs.filter(
|
|
597
589
|
(gen_ecs) => gen_ecs.donnee_entree.enum_type_energie_id === energie_id
|
|
598
590
|
);
|
|
599
|
-
|
|
591
|
+
|
|
592
|
+
if (type_energie === 'électricité') {
|
|
593
|
+
acc.push({
|
|
594
|
+
...sortieElectricite(
|
|
595
|
+
Sh,
|
|
596
|
+
zc_id,
|
|
597
|
+
vt,
|
|
598
|
+
gen_ch,
|
|
599
|
+
gen_ecs,
|
|
600
|
+
gen_ch_en,
|
|
601
|
+
gen_ecs_en,
|
|
602
|
+
fr,
|
|
603
|
+
ecs,
|
|
604
|
+
prorataECS,
|
|
605
|
+
prorataChauffage,
|
|
606
|
+
facteursAc
|
|
607
|
+
),
|
|
608
|
+
enum_type_energie_id: energie_id
|
|
609
|
+
});
|
|
610
|
+
return acc;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
const conso_en = calc_conso_pond(
|
|
600
614
|
Sh,
|
|
601
615
|
zc_id,
|
|
602
|
-
|
|
616
|
+
[],
|
|
603
617
|
gen_ch_en,
|
|
604
618
|
gen_ecs_en,
|
|
605
|
-
|
|
619
|
+
[],
|
|
606
620
|
'',
|
|
607
621
|
null,
|
|
608
622
|
prorataECS,
|
|
609
623
|
prorataChauffage,
|
|
610
|
-
|
|
624
|
+
[]
|
|
611
625
|
);
|
|
612
|
-
|
|
626
|
+
acc.push({
|
|
613
627
|
conso_ch: conso_en._ch,
|
|
614
628
|
conso_ecs: conso_en._ecs,
|
|
615
|
-
|
|
629
|
+
// Énergie non électrique : chauffage + ECS uniquement, l'éclairage, le froid et les
|
|
630
|
+
// auxiliaires étant électriques (portés par la ligne électricité)
|
|
631
|
+
conso_5_usages: conso_en._ch + conso_en._ecs,
|
|
616
632
|
emission_ges_ch: conso_en._ch * coef_ges[getCoefKey(type_energie, 'ch')],
|
|
617
633
|
emission_ges_ecs: conso_en._ecs * coef_ges[getCoefKey(type_energie, 'ecs')],
|
|
618
|
-
|
|
619
|
-
};
|
|
620
|
-
|
|
621
|
-
|
|
634
|
+
enum_type_energie_id: energie_id
|
|
635
|
+
});
|
|
636
|
+
const ligne = acc[acc.length - 1];
|
|
637
|
+
ligne.emission_ges_5_usages = ligne.emission_ges_ch + ligne.emission_ges_ecs;
|
|
638
|
+
return acc;
|
|
622
639
|
}, []);
|
|
623
640
|
return ret;
|
|
624
641
|
}
|
|
625
642
|
|
|
643
|
+
/**
|
|
644
|
+
* Ligne « électricité » de sortie_par_energie (issue #34).
|
|
645
|
+
*
|
|
646
|
+
* - Chauffage et ECS : générateurs électriques uniquement.
|
|
647
|
+
* - Auxiliaires (génération et distribution ch/ecs, ventilation) : toujours électriques, quelle
|
|
648
|
+
* que soit l'énergie du générateur (§15, §16.2 : « consommation annuelle d'électricité pour les
|
|
649
|
+
* auxiliaires »), donc rattachés à l'électricité pour tous les générateurs.
|
|
650
|
+
* - Éclairage et froid électrique (un réseau de froid relève d'une autre énergie).
|
|
651
|
+
* - Émissions : coefficient GES propre à chaque usage (ch 0,079, ecs 0,065, fr 0,064,
|
|
652
|
+
* éclairage 0,069, auxiliaires 0,064), aucun coefficient « électricité » global n'existant.
|
|
653
|
+
* - facteursAc : consommations nettes de l'autoconsommation PV par usage (arrêté DPE habitation
|
|
654
|
+
* §3.a, méthode §16.2) ; vide pour le calcul brut servant au taux de couverture PV.
|
|
655
|
+
*
|
|
656
|
+
* @return {{conso_ch: number, conso_ecs: number, conso_5_usages: number, emission_ges_ch: number, emission_ges_ecs: number, emission_ges_5_usages: number}}
|
|
657
|
+
*/
|
|
658
|
+
export function sortieElectricite(
|
|
659
|
+
Sh,
|
|
660
|
+
zc_id,
|
|
661
|
+
vt,
|
|
662
|
+
gen_ch,
|
|
663
|
+
gen_ecs,
|
|
664
|
+
gen_ch_elec,
|
|
665
|
+
gen_ecs_elec,
|
|
666
|
+
fr,
|
|
667
|
+
ecs,
|
|
668
|
+
prorataECS,
|
|
669
|
+
prorataChauffage,
|
|
670
|
+
facteursAc = {}
|
|
671
|
+
) {
|
|
672
|
+
const fr_elec = fr.filter((f) => getTypeEnergie(f.donnee_entree, 'fr') === 'électricité fr');
|
|
673
|
+
const postes = (coef) => {
|
|
674
|
+
const usages = calc_conso_pond(
|
|
675
|
+
Sh,
|
|
676
|
+
zc_id,
|
|
677
|
+
[],
|
|
678
|
+
gen_ch_elec,
|
|
679
|
+
gen_ecs_elec,
|
|
680
|
+
[],
|
|
681
|
+
'',
|
|
682
|
+
coef,
|
|
683
|
+
prorataECS,
|
|
684
|
+
prorataChauffage,
|
|
685
|
+
[],
|
|
686
|
+
facteursAc
|
|
687
|
+
);
|
|
688
|
+
const communs = calc_conso_pond(
|
|
689
|
+
Sh,
|
|
690
|
+
zc_id,
|
|
691
|
+
vt,
|
|
692
|
+
gen_ch,
|
|
693
|
+
gen_ecs,
|
|
694
|
+
fr_elec,
|
|
695
|
+
'',
|
|
696
|
+
coef,
|
|
697
|
+
prorataECS,
|
|
698
|
+
prorataChauffage,
|
|
699
|
+
ecs,
|
|
700
|
+
facteursAc
|
|
701
|
+
);
|
|
702
|
+
return {
|
|
703
|
+
ch: usages._ch,
|
|
704
|
+
ecs: usages._ecs,
|
|
705
|
+
total:
|
|
706
|
+
usages._ch + usages._ecs + communs._fr + communs._totale_auxiliaire + communs._eclairage
|
|
707
|
+
};
|
|
708
|
+
};
|
|
709
|
+
const conso = postes(null);
|
|
710
|
+
const ges = postes(coef_ges);
|
|
711
|
+
return {
|
|
712
|
+
conso_ch: conso.ch,
|
|
713
|
+
conso_ecs: conso.ecs,
|
|
714
|
+
conso_5_usages: conso.total,
|
|
715
|
+
emission_ges_ch: ges.ch,
|
|
716
|
+
emission_ges_ecs: ges.ecs,
|
|
717
|
+
emission_ges_5_usages: ges.total
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
|
|
626
721
|
export function classe_bilan_dpe(ep_conso_5_usages_m2, zc_id, ca_id, Sh) {
|
|
627
722
|
const ca = enums.classe_altitude[ca_id];
|
|
628
723
|
|
package/conso.spec.js
CHANGED
|
@@ -622,6 +622,91 @@ describe('calc_conso - agrégation des consommations', () => {
|
|
|
622
622
|
});
|
|
623
623
|
});
|
|
624
624
|
|
|
625
|
+
/**
|
|
626
|
+
* Ligne « électricité » de sortie_par_energie (issue #34).
|
|
627
|
+
* @see : Methode_de_calcul_3CL_DPE_2021-338.pdf - §15, §16.2 ; arrêté DPE habitation du 31/03/2021 §3.a, §4.a
|
|
628
|
+
*/
|
|
629
|
+
describe('sortie_par_energie - ligne électricité (issue #34)', () => {
|
|
630
|
+
const elecDe = (res) =>
|
|
631
|
+
res.sortie_par_energie_collection.sortie_par_energie.find(
|
|
632
|
+
(e) => e.enum_type_energie_id === '1'
|
|
633
|
+
);
|
|
634
|
+
|
|
635
|
+
/** Chaudière gaz avec auxiliaires de génération et de distribution (électriques). */
|
|
636
|
+
const chGaz = () => [
|
|
637
|
+
installCh({ cle_repartition_ch: 1 }, [
|
|
638
|
+
genCh('2', {
|
|
639
|
+
conso_ch: 10000,
|
|
640
|
+
conso_ch_depensier: 12000,
|
|
641
|
+
conso_auxiliaire_generation_ch: 100,
|
|
642
|
+
conso_auxiliaire_distribution_ch: 50
|
|
643
|
+
})
|
|
644
|
+
])
|
|
645
|
+
];
|
|
646
|
+
|
|
647
|
+
test('chaudière gaz : auxiliaires rattachés à l’électricité, GES = Σ postes × coefficient par usage', () => {
|
|
648
|
+
const res = calc_conso(100, 1, 1, [], chGaz(), [], [], 1, 1, DATE_DPE, coef_ep);
|
|
649
|
+
const elec = elecDe(res);
|
|
650
|
+
|
|
651
|
+
// Pas de chauffage électrique ; éclairage = 1 × Sh = 100 ; auxiliaires = 100 + 50
|
|
652
|
+
expect(elec.conso_ch).toBe(0);
|
|
653
|
+
expect(elec.conso_5_usages).toBeCloseTo(100 + 150, 9);
|
|
654
|
+
// 100 × 0,069 (éclairage) + 150 × 0,064 (auxiliaires)
|
|
655
|
+
expect(elec.emission_ges_5_usages).toBeCloseTo(100 * 0.069 + 150 * 0.064, 9);
|
|
656
|
+
// La ligne gaz ne porte plus les auxiliaires
|
|
657
|
+
const gaz = res.sortie_par_energie_collection.sortie_par_energie.find(
|
|
658
|
+
(e) => e.enum_type_energie_id === '2'
|
|
659
|
+
);
|
|
660
|
+
expect(gaz.conso_5_usages).toBeCloseTo(10000, 9);
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
test('somme des lignes par énergie = totaux 5 usages (EF et GES)', () => {
|
|
664
|
+
const ecs = [installEcs({}, [genEcs('1', { conso_ecs: 1000, conso_ecs_depensier: 1100 })])];
|
|
665
|
+
const vt = [{ donnee_entree: {}, donnee_intermediaire: { conso_auxiliaire_ventilation: 40 } }];
|
|
666
|
+
const res = calc_conso(100, 1, 1, vt, chGaz(), ecs, [], 1, 1, DATE_DPE, coef_ep);
|
|
667
|
+
const lignes = res.sortie_par_energie_collection.sortie_par_energie;
|
|
668
|
+
const somme = (k) => lignes.reduce((acc, l) => acc + l[k], 0);
|
|
669
|
+
|
|
670
|
+
expect(somme('conso_5_usages')).toBeCloseTo(res.ef_conso.conso_5_usages, 9);
|
|
671
|
+
expect(somme('emission_ges_5_usages')).toBeCloseTo(res.emission_ges.emission_ges_5_usages, 9);
|
|
672
|
+
// ECS électrique au coefficient ECS (0,065)
|
|
673
|
+
expect(elecDe(res).emission_ges_ecs).toBeCloseTo(1000 * 0.065, 9);
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
test('froid : électrique compté dans la ligne électricité, réseau de froid exclu', () => {
|
|
677
|
+
const frElec = [
|
|
678
|
+
{ donnee_entree: { enum_type_energie_id: '1' }, donnee_intermediaire: { conso_fr: 200 } }
|
|
679
|
+
];
|
|
680
|
+
const frReseau = [
|
|
681
|
+
{ donnee_entree: { enum_type_energie_id: '3' }, donnee_intermediaire: { conso_fr: 200 } }
|
|
682
|
+
];
|
|
683
|
+
const avecElec = elecDe(calc_conso(100, 1, 1, [], [], [], frElec, 1, 1, DATE_DPE, coef_ep));
|
|
684
|
+
const avecReseau = elecDe(calc_conso(100, 1, 1, [], [], [], frReseau, 1, 1, DATE_DPE, coef_ep));
|
|
685
|
+
|
|
686
|
+
expect(avecElec.conso_5_usages).toBeCloseTo(100 + 200, 9);
|
|
687
|
+
expect(avecElec.emission_ges_5_usages).toBeCloseTo(100 * 0.069 + 200 * 0.064, 9);
|
|
688
|
+
expect(avecReseau.conso_5_usages).toBeCloseTo(100, 9);
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
test('autoconsommation PV : ligne électricité nette, usage par usage', () => {
|
|
692
|
+
const facteursAc = { eclairage: 0.5, auxiliaire_generation_ch: 0.8 };
|
|
693
|
+
const net = elecDe(
|
|
694
|
+
calc_conso(100, 1, 1, [], chGaz(), [], [], 1, 1, DATE_DPE, coef_ep, 1, 1, facteursAc)
|
|
695
|
+
);
|
|
696
|
+
|
|
697
|
+
// éclairage 100 × 0,5 ; génération 100 × 0,8 ; distribution 50 inchangée
|
|
698
|
+
expect(net.conso_5_usages).toBeCloseTo(50 + 80 + 50, 9);
|
|
699
|
+
expect(net.emission_ges_5_usages).toBeCloseTo(50 * 0.069 + (80 + 50) * 0.064, 9);
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
test('aucune émission NaN sur la ligne électricité', () => {
|
|
703
|
+
const res = calc_conso(100, 1, 1, [], chGaz(), [], [], 1, 1, DATE_DPE, coef_ep);
|
|
704
|
+
for (const ligne of res.sortie_par_energie_collection.sortie_par_energie) {
|
|
705
|
+
expect(Number.isFinite(ligne.emission_ges_5_usages)).toBe(true);
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
});
|
|
709
|
+
|
|
625
710
|
/**
|
|
626
711
|
* Barème des prix des énergies selon la date d'établissement du DPE.
|
|
627
712
|
* Barème 2021 : Annexe 7 de l'arrêté du 31/03/2021.
|
package/engine.js
CHANGED
|
@@ -33,7 +33,7 @@ import getFicheTechnique from './ficheTechnique.js';
|
|
|
33
33
|
import { ProductionENR, ratioProrataPvLogement } from './16.2_production_enr.js';
|
|
34
34
|
import DpeSanitizerService from './dpe-sanitizer.service.js';
|
|
35
35
|
|
|
36
|
-
const LIB_VERSION = '1.8.
|
|
36
|
+
const LIB_VERSION = '1.8.47';
|
|
37
37
|
|
|
38
38
|
const dpeSanitizerService = new DpeSanitizerService();
|
|
39
39
|
|
|
@@ -651,6 +651,8 @@ export function calcul_3cl(inputDpe, options) {
|
|
|
651
651
|
facteursAc
|
|
652
652
|
);
|
|
653
653
|
conso.emission_ges = consoNette.emission_ges;
|
|
654
|
+
// Ligne électricité de sortie_par_energie nette de l'autoconsommation (issue #34)
|
|
655
|
+
conso.sortie_par_energie_collection = consoNette.sortie_par_energie_collection;
|
|
654
656
|
conso.cout = consoNette.cout;
|
|
655
657
|
}
|
|
656
658
|
|