@open3cl/engine 1.8.42 → 1.8.43
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/16.2_production_enr.js +64 -1
- package/16.2_production_enr.spec.js +102 -0
- package/README.md +14 -14
- package/conso.js +49 -28
- package/conso.spec.js +115 -0
- package/engine.js +29 -2
- package/engine.spec.js +40 -1
- package/package.json +1 -1
package/16.2_production_enr.js
CHANGED
|
@@ -62,8 +62,18 @@ export class ProductionENR {
|
|
|
62
62
|
* @param zc_id {string}
|
|
63
63
|
* @param coeff_ep_override {number?}
|
|
64
64
|
* @param ratioPv {number?} proratisation au logement d'une installation d'immeuble (cf. ratioProrataPvLogement)
|
|
65
|
+
* @param facteursAc {object?} si fourni, reçoit par poste la part non autoconsommée (cf. getFacteursNonAutoconsommes)
|
|
65
66
|
*/
|
|
66
|
-
calculateEnr(
|
|
67
|
+
calculateEnr(
|
|
68
|
+
productionElecEnr,
|
|
69
|
+
conso,
|
|
70
|
+
Sh,
|
|
71
|
+
th,
|
|
72
|
+
zc_id,
|
|
73
|
+
coeff_ep_override,
|
|
74
|
+
ratioPv = 1,
|
|
75
|
+
facteursAc = null
|
|
76
|
+
) {
|
|
67
77
|
const productionElectricite = {
|
|
68
78
|
conso_elec_ac: 0,
|
|
69
79
|
production_pv: 0,
|
|
@@ -92,6 +102,10 @@ export class ProductionENR {
|
|
|
92
102
|
ratioPv
|
|
93
103
|
);
|
|
94
104
|
|
|
105
|
+
if (facteursAc) {
|
|
106
|
+
Object.assign(facteursAc, this.getFacteursNonAutoconsommes(productionElectricite, conso));
|
|
107
|
+
}
|
|
108
|
+
|
|
95
109
|
// Mise à jour des consommations d'énergie finale en minorant l'énergie consommée par l'énergie autoconsommée par le poste
|
|
96
110
|
this.updateEfConso(productionElectricite, conso, Sh);
|
|
97
111
|
|
|
@@ -213,6 +227,55 @@ export class ProductionENR {
|
|
|
213
227
|
productionElectricite.conso_elec_ac_auxiliaire = consoAcAuxiliaires;
|
|
214
228
|
}
|
|
215
229
|
|
|
230
|
+
/**
|
|
231
|
+
* Part non autoconsommée (1 − Celec_ac_poste / Celec_poste) de la consommation électrique de chaque
|
|
232
|
+
* poste, à appliquer aux consommations électriques avant calcul des émissions GES et du coût.
|
|
233
|
+
*
|
|
234
|
+
* Le moteur de référence calcule les émissions et les coûts sur les consommations électriques
|
|
235
|
+
* minorées de l'autoconsommation PV (Tribu `Calcul_batiment.cs` l.1188 carbone_total :
|
|
236
|
+
* (Cch_electricite − Celec_ac_ch) × 0,079 + … ; l.1318 calc_cout.Calcul(…, num19 − num60, …)).
|
|
237
|
+
* Doit être appelée avant updateEfConso (consommations encore brutes).
|
|
238
|
+
*
|
|
239
|
+
* @param productionElectricite autoconsommation par poste (calculateConsoElecAc)
|
|
240
|
+
* @param conso consommations brutes (ef_conso, sortie_par_energie_collection)
|
|
241
|
+
* @returns {Object<string, number>} facteur par poste : ch, ecs, fr, eclairage, ventilation,
|
|
242
|
+
* auxiliaire_generation_ch, auxiliaire_generation_ecs, auxiliaire_distribution_ch,
|
|
243
|
+
* auxiliaire_distribution_ecs
|
|
244
|
+
*/
|
|
245
|
+
getFacteursNonAutoconsommes(productionElectricite, conso) {
|
|
246
|
+
const consoElec = conso.sortie_par_energie_collection.sortie_par_energie.find(
|
|
247
|
+
(sortie) => sortie.enum_type_energie_id === '1'
|
|
248
|
+
);
|
|
249
|
+
const ef = conso.ef_conso;
|
|
250
|
+
const facteur = (ac, brut) => (brut > 0 ? 1 - ac / brut : 1);
|
|
251
|
+
return {
|
|
252
|
+
ch: facteur(productionElectricite.conso_elec_ac_ch, consoElec?.conso_ch),
|
|
253
|
+
ecs: facteur(productionElectricite.conso_elec_ac_ecs, consoElec?.conso_ecs),
|
|
254
|
+
fr: facteur(productionElectricite.conso_elec_ac_fr, ef.conso_fr),
|
|
255
|
+
eclairage: facteur(productionElectricite.conso_elec_ac_eclairage, ef.conso_eclairage),
|
|
256
|
+
ventilation: facteur(
|
|
257
|
+
productionElectricite.conso_elec_ac_ventilation,
|
|
258
|
+
ef.conso_auxiliaire_ventilation
|
|
259
|
+
),
|
|
260
|
+
auxiliaire_generation_ch: facteur(
|
|
261
|
+
productionElectricite.conso_elec_ac_auxiliaire_generation_ch,
|
|
262
|
+
ef.conso_auxiliaire_generation_ch
|
|
263
|
+
),
|
|
264
|
+
auxiliaire_generation_ecs: facteur(
|
|
265
|
+
productionElectricite.conso_elec_ac_auxiliaire_generation_ecs,
|
|
266
|
+
ef.conso_auxiliaire_generation_ecs
|
|
267
|
+
),
|
|
268
|
+
auxiliaire_distribution_ch: facteur(
|
|
269
|
+
productionElectricite.conso_elec_ac_auxiliaire_distribution_ch,
|
|
270
|
+
ef.conso_auxiliaire_distribution_ch
|
|
271
|
+
),
|
|
272
|
+
auxiliaire_distribution_ecs: facteur(
|
|
273
|
+
productionElectricite.conso_elec_ac_auxiliaire_distribution_ecs,
|
|
274
|
+
ef.conso_auxiliaire_distribution_ecs
|
|
275
|
+
)
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
|
|
216
279
|
/**
|
|
217
280
|
* Mise à jour des consommations ef en minorant l'énergie finale consommée par l'énergie autoconsommée par chaque enveloppe
|
|
218
281
|
* @param productionElectricite
|
|
@@ -72,6 +72,108 @@ describe('production ENR unit tests', () => {
|
|
|
72
72
|
}
|
|
73
73
|
);
|
|
74
74
|
|
|
75
|
+
test('getFacteursNonAutoconsommes : part non autoconsommée de chaque poste électrique', () => {
|
|
76
|
+
const productionElectricite = {
|
|
77
|
+
conso_elec_ac_ch: 250,
|
|
78
|
+
conso_elec_ac_ecs: 0,
|
|
79
|
+
conso_elec_ac_fr: 0,
|
|
80
|
+
conso_elec_ac_eclairage: 50,
|
|
81
|
+
conso_elec_ac_ventilation: 30,
|
|
82
|
+
conso_elec_ac_auxiliaire_generation_ch: 0,
|
|
83
|
+
conso_elec_ac_auxiliaire_generation_ecs: 0,
|
|
84
|
+
conso_elec_ac_auxiliaire_distribution_ch: 10,
|
|
85
|
+
conso_elec_ac_auxiliaire_distribution_ecs: 0
|
|
86
|
+
};
|
|
87
|
+
const conso = {
|
|
88
|
+
ef_conso: {
|
|
89
|
+
conso_fr: 0,
|
|
90
|
+
conso_eclairage: 100,
|
|
91
|
+
conso_auxiliaire_ventilation: 120,
|
|
92
|
+
conso_auxiliaire_generation_ch: 0,
|
|
93
|
+
conso_auxiliaire_generation_ecs: 0,
|
|
94
|
+
conso_auxiliaire_distribution_ch: 40,
|
|
95
|
+
conso_auxiliaire_distribution_ecs: 0
|
|
96
|
+
},
|
|
97
|
+
sortie_par_energie_collection: {
|
|
98
|
+
sortie_par_energie: [
|
|
99
|
+
{ enum_type_energie_id: '2', conso_ch: 5000, conso_ecs: 2000 },
|
|
100
|
+
{ enum_type_energie_id: '1', conso_ch: 1000, conso_ecs: 0 }
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
expect(productionENR.getFacteursNonAutoconsommes(productionElectricite, conso)).toStrictEqual({
|
|
105
|
+
ch: 0.75,
|
|
106
|
+
ecs: 1,
|
|
107
|
+
fr: 1,
|
|
108
|
+
eclairage: 0.5,
|
|
109
|
+
ventilation: 0.75,
|
|
110
|
+
auxiliaire_generation_ch: 1,
|
|
111
|
+
auxiliaire_generation_ecs: 1,
|
|
112
|
+
auxiliaire_distribution_ch: 0.75,
|
|
113
|
+
auxiliaire_distribution_ecs: 1
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('calculateEnr renseigne les facteurs avant minoration des consommations', () => {
|
|
118
|
+
const conso = {
|
|
119
|
+
ef_conso: {
|
|
120
|
+
conso_ch: 1000,
|
|
121
|
+
conso_ecs: 0,
|
|
122
|
+
conso_fr: 0,
|
|
123
|
+
conso_eclairage: 100,
|
|
124
|
+
conso_auxiliaire_ventilation: 0,
|
|
125
|
+
conso_auxiliaire_generation_ch: 0,
|
|
126
|
+
conso_auxiliaire_generation_ecs: 0,
|
|
127
|
+
conso_auxiliaire_distribution_ch: 0,
|
|
128
|
+
conso_auxiliaire_distribution_ecs: 0,
|
|
129
|
+
conso_totale_auxiliaire: 0,
|
|
130
|
+
conso_5_usages: 1100,
|
|
131
|
+
conso_5_usages_m2: 11
|
|
132
|
+
},
|
|
133
|
+
ep_conso: {
|
|
134
|
+
ep_conso_ch: 1900,
|
|
135
|
+
ep_conso_ecs: 0,
|
|
136
|
+
ep_conso_fr: 0,
|
|
137
|
+
ep_conso_eclairage: 190,
|
|
138
|
+
ep_conso_totale_auxiliaire: 0,
|
|
139
|
+
ep_conso_5_usages: 2090,
|
|
140
|
+
ep_conso_5_usages_m2: 20.9
|
|
141
|
+
},
|
|
142
|
+
sortie_par_energie_collection: {
|
|
143
|
+
sortie_par_energie: [
|
|
144
|
+
{ enum_type_energie_id: '1', conso_ch: 1000, conso_ecs: 0, conso_5_usages: 1100 }
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
const facteursAc = {};
|
|
149
|
+
productionENR.calculateEnr(
|
|
150
|
+
{
|
|
151
|
+
donnee_entree: { presence_production_pv: 1 },
|
|
152
|
+
panneaux_pv_collection: {
|
|
153
|
+
panneaux_pv: [
|
|
154
|
+
{
|
|
155
|
+
enum_orientation_pv_id: '3',
|
|
156
|
+
enum_inclinaison_pv_id: '2',
|
|
157
|
+
surface_totale_capteurs: 10
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
conso,
|
|
163
|
+
100,
|
|
164
|
+
'maison',
|
|
165
|
+
1,
|
|
166
|
+
undefined,
|
|
167
|
+
1,
|
|
168
|
+
facteursAc
|
|
169
|
+
);
|
|
170
|
+
expect(facteursAc.ch).toBeGreaterThan(0);
|
|
171
|
+
expect(facteursAc.ch).toBeLessThan(1);
|
|
172
|
+
expect(facteursAc.eclairage).toBeGreaterThanOrEqual(0);
|
|
173
|
+
expect(facteursAc.eclairage).toBeLessThan(1);
|
|
174
|
+
expect(facteursAc.ecs).toBe(1);
|
|
175
|
+
});
|
|
176
|
+
|
|
75
177
|
describe('proratisation au logement des installations PV d’immeuble', () => {
|
|
76
178
|
const panneau = (extra = {}) => ({
|
|
77
179
|
panneaux_pv_collection: {
|
package/README.md
CHANGED
|
@@ -370,7 +370,7 @@ 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.42`** · branche `main` · généré le 2026-10-10
|
|
374
374
|
> Seuil de tolérance **5%**
|
|
375
375
|
|
|
376
376
|
<table>
|
|
@@ -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>
|
|
407
|
-
<td align="center"><strong>4,
|
|
408
|
-
<td align="center"><strong>0,
|
|
409
|
-
<td align="center"><strong>
|
|
406
|
+
<td align="center"><strong>4,78 ms</strong><br/><sub>moyenne</sub></td>
|
|
407
|
+
<td align="center"><strong>4,16 ms</strong><br/><sub>médiane</sub></td>
|
|
408
|
+
<td align="center"><strong>0,11 ms</strong><br/><sub>min</sub></td>
|
|
409
|
+
<td align="center"><strong>675,9 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** | 4,
|
|
416
|
-
| **Appartement · chauffage individuel (2025)** | 3,
|
|
417
|
-
| **Logement individuel (2025)** |
|
|
418
|
-
| **Maison individuelle (2025)** | 5,
|
|
419
|
-
| **Immeuble · chauffage individuel** | 6,
|
|
420
|
-
| **Appartement · chauffage collectif (2025)** | 4,
|
|
421
|
-
| **Immeuble · chauffage collectif** | 5,
|
|
422
|
-
| **Immeuble · chauffage mixte** | 4,
|
|
423
|
-
| **Individuel généré depuis l'immeuble (2026)** | 5,
|
|
415
|
+
| **Généraliste** | 4,07 ms | 3,65 ms | 0,21 ms | 29,1 ms | 7,39 ms | 10,1 ms |
|
|
416
|
+
| **Appartement · chauffage individuel (2025)** | 3,68 ms | 3,34 ms | 1,47 ms | 31,2 ms | 6,40 ms | 8,41 ms |
|
|
417
|
+
| **Logement individuel (2025)** | 4,46 ms | 3,96 ms | 1,53 ms | 34,6 ms | 8,25 ms | 11,2 ms |
|
|
418
|
+
| **Maison individuelle (2025)** | 5,34 ms | 4,83 ms | 1,83 ms | 37,7 ms | 9,56 ms | 12,2 ms |
|
|
419
|
+
| **Immeuble · chauffage individuel** | 6,00 ms | 5,10 ms | 0,11 ms | 76,6 ms | 12,2 ms | 19,3 ms |
|
|
420
|
+
| **Appartement · chauffage collectif (2025)** | 4,08 ms | 3,68 ms | 1,47 ms | 31,1 ms | 6,74 ms | 8,48 ms |
|
|
421
|
+
| **Immeuble · chauffage collectif** | 5,15 ms | 4,34 ms | 0,12 ms | 99,4 ms | 9,51 ms | 16,3 ms |
|
|
422
|
+
| **Immeuble · chauffage mixte** | 4,96 ms | 4,07 ms | 0,18 ms | 675,9 ms | 10,2 ms | 16,5 ms |
|
|
423
|
+
| **Individuel généré depuis l'immeuble (2026)** | 5,26 ms | 4,46 ms | 1,65 ms | 54,8 ms | 10,2 ms | 15,1 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
|
@@ -376,7 +376,8 @@ export default function calc_conso(
|
|
|
376
376
|
dateDpe,
|
|
377
377
|
coeffEp,
|
|
378
378
|
nbLogements = 1,
|
|
379
|
-
ratioSurfaceCollectif = 1
|
|
379
|
+
ratioSurfaceCollectif = 1,
|
|
380
|
+
facteursAc = {}
|
|
380
381
|
) {
|
|
381
382
|
const gen_ch = ch.reduce((acc, ch) => {
|
|
382
383
|
const generateur_chauffage = ch.generateur_chauffage_collection.generateur_chauffage;
|
|
@@ -399,9 +400,6 @@ export default function calc_conso(
|
|
|
399
400
|
|
|
400
401
|
ecs = Array.isArray(ecs) ? ecs : [];
|
|
401
402
|
|
|
402
|
-
const conso_aux_distribution_ecs_total = ecs.reduce((acc, ecs) => {
|
|
403
|
-
return acc + (ecs.donnee_intermediaire.conso_auxiliaire_distribution_ecs || 0);
|
|
404
|
-
}, 0);
|
|
405
403
|
const gen_ecs = ecs.reduce((acc, ecs) => {
|
|
406
404
|
const generateur_ecs = ecs.generateur_ecs_collection.generateur_ecs;
|
|
407
405
|
if (prorataECS === 1) {
|
|
@@ -416,6 +414,14 @@ export default function calc_conso(
|
|
|
416
414
|
return acc.concat(generateur_ecs);
|
|
417
415
|
}, []);
|
|
418
416
|
|
|
417
|
+
/**
|
|
418
|
+
* Coût : le moteur de référence ne minore de l'autoconsommation PV que le chauffage, l'ECS et les
|
|
419
|
+
* auxiliaires de génération / distribution ; l'éclairage, le froid et la ventilation sont tarifés
|
|
420
|
+
* bruts (Tribu `Calcul_batiment.cs` l.1318 : num31 = Ceclairage1, conso_elec_*_fr,
|
|
421
|
+
* conso_elec_*_vent passés sans déduction à calc_cout.Calcul).
|
|
422
|
+
*/
|
|
423
|
+
const facteursAcCout = { ...facteursAc, eclairage: 1, fr: 1, ventilation: 1 };
|
|
424
|
+
|
|
419
425
|
/**
|
|
420
426
|
* Barème des coûts : barème 2021 (par poste) avant le 01/07/2024 ; ensuite barème mis à jour
|
|
421
427
|
* avec tranche déterminée sur la consommation totale de l'énergie (voir coefCoutProrata).
|
|
@@ -456,7 +462,8 @@ export default function calc_conso(
|
|
|
456
462
|
masque,
|
|
457
463
|
prorataECS,
|
|
458
464
|
prorataChauffage,
|
|
459
|
-
ecs
|
|
465
|
+
ecs,
|
|
466
|
+
facteursAcCout
|
|
460
467
|
);
|
|
461
468
|
const coll = calc_conso_pond(
|
|
462
469
|
0,
|
|
@@ -469,7 +476,8 @@ export default function calc_conso(
|
|
|
469
476
|
masque,
|
|
470
477
|
prorataECS,
|
|
471
478
|
prorataChauffage,
|
|
472
|
-
[]
|
|
479
|
+
[],
|
|
480
|
+
facteursAcCout
|
|
473
481
|
);
|
|
474
482
|
// Appoint individuel des convecteurs bi-jonction : tarifé en individuel (voir coutBijonction)
|
|
475
483
|
const appointIndividuel = gen_ch
|
|
@@ -502,8 +510,7 @@ export default function calc_conso(
|
|
|
502
510
|
null,
|
|
503
511
|
prorataECS,
|
|
504
512
|
prorataChauffage,
|
|
505
|
-
ecs
|
|
506
|
-
conso_aux_distribution_ecs_total
|
|
513
|
+
ecs
|
|
507
514
|
),
|
|
508
515
|
ep_conso: calc_conso_pond(
|
|
509
516
|
Sh,
|
|
@@ -516,8 +523,7 @@ export default function calc_conso(
|
|
|
516
523
|
coeffEp,
|
|
517
524
|
prorataECS,
|
|
518
525
|
prorataChauffage,
|
|
519
|
-
ecs
|
|
520
|
-
conso_aux_distribution_ecs_total
|
|
526
|
+
ecs
|
|
521
527
|
),
|
|
522
528
|
emission_ges: calc_conso_pond(
|
|
523
529
|
Sh,
|
|
@@ -531,7 +537,7 @@ export default function calc_conso(
|
|
|
531
537
|
prorataECS,
|
|
532
538
|
prorataChauffage,
|
|
533
539
|
ecs,
|
|
534
|
-
|
|
540
|
+
facteursAc
|
|
535
541
|
),
|
|
536
542
|
cout: calc_conso_pond(
|
|
537
543
|
Sh,
|
|
@@ -545,7 +551,7 @@ export default function calc_conso(
|
|
|
545
551
|
prorataECS,
|
|
546
552
|
prorataChauffage,
|
|
547
553
|
ecs,
|
|
548
|
-
|
|
554
|
+
facteursAcCout
|
|
549
555
|
)
|
|
550
556
|
};
|
|
551
557
|
ret.ep_conso.classe_bilan_dpe = classe_bilan_dpe(
|
|
@@ -670,12 +676,14 @@ export function classe_emission_ges(emission_ges_5_usages_m2, zc_id, ca_id, Sh)
|
|
|
670
676
|
* @param coef {number}
|
|
671
677
|
* @param prorataECS {number}
|
|
672
678
|
* @param prefix {string}
|
|
679
|
+
* @param facteurAc {number} part non autoconsommée (PV) de l'ECS électrique (1 sans PV)
|
|
673
680
|
* @returns {number}
|
|
674
681
|
*/
|
|
675
|
-
function getEcsConso(gen_ecs, field, coef, prorataECS, prefix) {
|
|
682
|
+
function getEcsConso(gen_ecs, field, coef, prorataECS, prefix, facteurAc = 1) {
|
|
676
683
|
return gen_ecs.reduce((acc, gen_ecs) => {
|
|
677
|
-
const conso = gen_ecs.donnee_intermediaire[field];
|
|
678
684
|
const typeEnergie = getTypeEnergie(gen_ecs.donnee_entree, 'ecs');
|
|
685
|
+
const conso =
|
|
686
|
+
gen_ecs.donnee_intermediaire[field] * (typeEnergie === 'électricité ecs' ? facteurAc : 1);
|
|
679
687
|
|
|
680
688
|
let coeffConsoEcs = { ...coefPourGenerateur(coef, gen_ecs) };
|
|
681
689
|
|
|
@@ -701,13 +709,14 @@ function getEcsConso(gen_ecs, field, coef, prorataECS, prefix) {
|
|
|
701
709
|
* @param field {string} conso_auxiliaire_generation_ecs[_depensier]
|
|
702
710
|
* @param coef {object}
|
|
703
711
|
* @param prorataECS {number}
|
|
712
|
+
* @param facteurAc {number} part non autoconsommée (PV) des auxiliaires de génération ECS
|
|
704
713
|
* @returns {number}
|
|
705
714
|
*/
|
|
706
|
-
export function getAuxGenerationEcs(ecs, field, coef, prorataECS) {
|
|
715
|
+
export function getAuxGenerationEcs(ecs, field, coef, prorataECS, facteurAc = 1) {
|
|
707
716
|
return ecs.reduce((acc, inst) => {
|
|
708
717
|
const rdim = prorataECS === 1 ? Number(inst.donnee_entree.rdim) || 1 : 1;
|
|
709
718
|
return inst.generateur_ecs_collection.generateur_ecs.reduce((acc2, gen) => {
|
|
710
|
-
const conso = (gen.donnee_intermediaire[field] || 0) * rdim;
|
|
719
|
+
const conso = (gen.donnee_intermediaire[field] || 0) * rdim * facteurAc;
|
|
711
720
|
return acc2 + getConso(coef, 'électricité auxiliaire', conso);
|
|
712
721
|
}, acc);
|
|
713
722
|
}, 0);
|
|
@@ -720,12 +729,14 @@ export function getAuxGenerationEcs(ecs, field, coef, prorataECS) {
|
|
|
720
729
|
* @param coef {number}
|
|
721
730
|
* @param prorataChauffage {number}
|
|
722
731
|
* @param prefix {string}
|
|
732
|
+
* @param facteurAc {number} part non autoconsommée (PV) du chauffage électrique (1 sans PV)
|
|
723
733
|
* @returns {number}
|
|
724
734
|
*/
|
|
725
|
-
function getChauffageConso(gen_ch, field, coef, prorataChauffage, prefix) {
|
|
735
|
+
function getChauffageConso(gen_ch, field, coef, prorataChauffage, prefix, facteurAc = 1) {
|
|
726
736
|
return gen_ch.reduce((acc, gen_ch) => {
|
|
727
|
-
const conso = gen_ch.donnee_intermediaire[field];
|
|
728
737
|
const typeEnergie = getTypeEnergie(gen_ch.donnee_entree, 'ch');
|
|
738
|
+
const conso =
|
|
739
|
+
gen_ch.donnee_intermediaire[field] * (typeEnergie === 'électricité ch' ? facteurAc : 1);
|
|
729
740
|
|
|
730
741
|
// La clé de répartition n'est utilisée que dans le cadre des chauffages collectifs
|
|
731
742
|
const repartition =
|
|
@@ -757,11 +768,13 @@ function calc_conso_pond(
|
|
|
757
768
|
coef,
|
|
758
769
|
prorataECS,
|
|
759
770
|
prorataChauffage,
|
|
760
|
-
ecs_installations
|
|
771
|
+
ecs_installations,
|
|
772
|
+
facteursAc = {}
|
|
761
773
|
) {
|
|
774
|
+
const fAc = (poste) => facteursAc[poste] ?? 1;
|
|
762
775
|
const ret = {};
|
|
763
776
|
ret.auxiliaire_ventilation = vt_list.reduce((acc, vt) => {
|
|
764
|
-
let conso = vt.donnee_intermediaire.conso_auxiliaire_ventilation || 0;
|
|
777
|
+
let conso = (vt.donnee_intermediaire.conso_auxiliaire_ventilation || 0) * fAc('ventilation');
|
|
765
778
|
|
|
766
779
|
if (vt.donnee_entree.cle_repartition_ventilation) {
|
|
767
780
|
conso *= vt.donnee_entree.cle_repartition_ventilation;
|
|
@@ -771,11 +784,13 @@ function calc_conso_pond(
|
|
|
771
784
|
}, 0);
|
|
772
785
|
|
|
773
786
|
const conso_eclairage = calc_conso_eclairage(zc_id) * Sh;
|
|
774
|
-
ret.eclairage = getConso(coef, 'électricité éclairage', conso_eclairage);
|
|
787
|
+
ret.eclairage = getConso(coef, 'électricité éclairage', conso_eclairage * fAc('eclairage'));
|
|
775
788
|
|
|
776
789
|
// aux ch
|
|
777
790
|
ret.auxiliaire_generation_ch = gen_ch.reduce((acc, gen_ch) => {
|
|
778
|
-
const conso =
|
|
791
|
+
const conso =
|
|
792
|
+
(gen_ch.donnee_intermediaire.conso_auxiliaire_generation_ch || 0) *
|
|
793
|
+
fAc('auxiliaire_generation_ch');
|
|
779
794
|
return acc + getConso(coef, 'électricité auxiliaire', conso);
|
|
780
795
|
}, 0);
|
|
781
796
|
|
|
@@ -785,7 +800,9 @@ function calc_conso_pond(
|
|
|
785
800
|
}, 0);
|
|
786
801
|
|
|
787
802
|
ret.auxiliaire_distribution_ch = gen_ch.reduce((acc, gen_ch) => {
|
|
788
|
-
let conso =
|
|
803
|
+
let conso =
|
|
804
|
+
(gen_ch.donnee_intermediaire.conso_auxiliaire_distribution_ch || 0) *
|
|
805
|
+
fAc('auxiliaire_distribution_ch');
|
|
789
806
|
|
|
790
807
|
/**
|
|
791
808
|
* enum_methode_calcul_conso_id
|
|
@@ -801,7 +818,7 @@ function calc_conso_pond(
|
|
|
801
818
|
return acc + getConso(coef, 'électricité auxiliaire', conso);
|
|
802
819
|
}, 0);
|
|
803
820
|
|
|
804
|
-
ret.ch = getChauffageConso(gen_ch, 'conso_ch', coef, prorataChauffage, prefix);
|
|
821
|
+
ret.ch = getChauffageConso(gen_ch, 'conso_ch', coef, prorataChauffage, prefix, fAc('ch'));
|
|
805
822
|
|
|
806
823
|
ret.ch_depensier = getChauffageConso(
|
|
807
824
|
gen_ch,
|
|
@@ -815,7 +832,8 @@ function calc_conso_pond(
|
|
|
815
832
|
ecs_installations,
|
|
816
833
|
'conso_auxiliaire_generation_ecs',
|
|
817
834
|
coef,
|
|
818
|
-
prorataECS
|
|
835
|
+
prorataECS,
|
|
836
|
+
fAc('auxiliaire_generation_ecs')
|
|
819
837
|
);
|
|
820
838
|
|
|
821
839
|
ret.auxiliaire_generation_ecs_depensier = getAuxGenerationEcs(
|
|
@@ -826,17 +844,20 @@ function calc_conso_pond(
|
|
|
826
844
|
);
|
|
827
845
|
|
|
828
846
|
ret.auxiliaire_distribution_ecs = ecs_installations.reduce((acc, inst) => {
|
|
829
|
-
const conso =
|
|
847
|
+
const conso =
|
|
848
|
+
(inst.donnee_intermediaire.conso_auxiliaire_distribution_ecs || 0) *
|
|
849
|
+
fAc('auxiliaire_distribution_ecs');
|
|
830
850
|
return acc + getConso(coef, 'électricité auxiliaire', conso);
|
|
831
851
|
}, 0);
|
|
832
852
|
|
|
833
|
-
ret.ecs = getEcsConso(gen_ecs, 'conso_ecs', coef, prorataECS, prefix);
|
|
853
|
+
ret.ecs = getEcsConso(gen_ecs, 'conso_ecs', coef, prorataECS, prefix, fAc('ecs'));
|
|
834
854
|
|
|
835
855
|
ret.ecs_depensier = getEcsConso(gen_ecs, 'conso_ecs_depensier', coef, prorataECS, prefix);
|
|
836
856
|
|
|
837
857
|
ret.fr = fr_list.reduce((acc, fr) => {
|
|
838
|
-
const conso = fr.donnee_intermediaire.conso_fr;
|
|
839
858
|
const typeEnergie = getTypeEnergie(fr.donnee_entree, 'fr');
|
|
859
|
+
const conso =
|
|
860
|
+
fr.donnee_intermediaire.conso_fr * (typeEnergie === 'électricité fr' ? fAc('fr') : 1);
|
|
840
861
|
|
|
841
862
|
return acc + getConso(coef, typeEnergie, conso);
|
|
842
863
|
}, 0);
|
package/conso.spec.js
CHANGED
|
@@ -238,6 +238,121 @@ describe('calc_conso - agrégation des consommations', () => {
|
|
|
238
238
|
expect(res.ef_conso.conso_eclairage).toBe(100);
|
|
239
239
|
});
|
|
240
240
|
|
|
241
|
+
test('autoconsommation PV : GES de tous les postes et coût hors éclairage/froid/ventilation minorés (Tribu Calcul_batiment.cs l.1188 / l.1318)', () => {
|
|
242
|
+
const ch = [
|
|
243
|
+
installCh({ cle_repartition_ch: 1 }, [
|
|
244
|
+
genCh('1', { conso_ch: 1000, conso_ch_depensier: 1200 })
|
|
245
|
+
])
|
|
246
|
+
];
|
|
247
|
+
// 25 % du chauffage et 50 % de l'éclairage autoconsommés
|
|
248
|
+
const facteursAc = { ch: 0.75, eclairage: 0.5 };
|
|
249
|
+
|
|
250
|
+
const brut = calc_conso(100, 1, 1, [], ch, [], [], 1, 1, DATE_DPE, coef_ep);
|
|
251
|
+
const net = calc_conso(100, 1, 1, [], ch, [], [], 1, 1, DATE_DPE, coef_ep, 1, 1, facteursAc);
|
|
252
|
+
|
|
253
|
+
// EF / EP inchangées (la minoration EF/EP reste faite par ProductionENR.updateEfConso)
|
|
254
|
+
expect(net.ef_conso).toStrictEqual(brut.ef_conso);
|
|
255
|
+
expect(net.ep_conso.ep_conso_5_usages).toBeCloseTo(brut.ep_conso.ep_conso_5_usages, 9);
|
|
256
|
+
// GES : 750 kWh × 0,079 ; éclairage 100 × 0,5 × coef
|
|
257
|
+
expect(net.emission_ges.emission_ges_ch).toBeCloseTo(750 * 0.079, 9);
|
|
258
|
+
expect(net.emission_ges.emission_ges_eclairage).toBeCloseTo(
|
|
259
|
+
brut.emission_ges.emission_ges_eclairage * 0.5,
|
|
260
|
+
9
|
|
261
|
+
);
|
|
262
|
+
// Coût : chauffage tarifé sur 750 kWh au lieu de 1000, éclairage tarifé brut
|
|
263
|
+
expect(net.cout.cout_ch).toBeLessThan(brut.cout.cout_ch);
|
|
264
|
+
expect(net.cout.cout_ch).toBeCloseTo(
|
|
265
|
+
calc_conso(
|
|
266
|
+
100,
|
|
267
|
+
1,
|
|
268
|
+
1,
|
|
269
|
+
[],
|
|
270
|
+
[
|
|
271
|
+
installCh({ cle_repartition_ch: 1 }, [
|
|
272
|
+
genCh('1', { conso_ch: 750, conso_ch_depensier: 900 })
|
|
273
|
+
])
|
|
274
|
+
],
|
|
275
|
+
[],
|
|
276
|
+
[],
|
|
277
|
+
1,
|
|
278
|
+
1,
|
|
279
|
+
DATE_DPE,
|
|
280
|
+
coef_ep
|
|
281
|
+
).cout.cout_ch,
|
|
282
|
+
9
|
|
283
|
+
);
|
|
284
|
+
expect(net.cout.cout_eclairage).toBeCloseTo(brut.cout.cout_eclairage, 9);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
test('autoconsommation PV : froid électrique minoré, froid non électrique non minoré', () => {
|
|
288
|
+
const frElec = [
|
|
289
|
+
{
|
|
290
|
+
donnee_entree: { enum_type_energie_id: '1' },
|
|
291
|
+
donnee_intermediaire: { conso_fr: 200, conso_fr_depensier: 250 }
|
|
292
|
+
}
|
|
293
|
+
];
|
|
294
|
+
const frGaz = [
|
|
295
|
+
{
|
|
296
|
+
donnee_entree: { enum_type_energie_id: '2' },
|
|
297
|
+
donnee_intermediaire: { conso_fr: 200, conso_fr_depensier: 250 }
|
|
298
|
+
}
|
|
299
|
+
];
|
|
300
|
+
const facteursAc = { fr: 0.5 };
|
|
301
|
+
|
|
302
|
+
const brutElec = calc_conso(100, 1, 1, [], [], [], frElec, 1, 1, DATE_DPE, coef_ep);
|
|
303
|
+
const netElec = calc_conso(
|
|
304
|
+
100,
|
|
305
|
+
1,
|
|
306
|
+
1,
|
|
307
|
+
[],
|
|
308
|
+
[],
|
|
309
|
+
[],
|
|
310
|
+
frElec,
|
|
311
|
+
1,
|
|
312
|
+
1,
|
|
313
|
+
DATE_DPE,
|
|
314
|
+
coef_ep,
|
|
315
|
+
1,
|
|
316
|
+
1,
|
|
317
|
+
facteursAc
|
|
318
|
+
);
|
|
319
|
+
expect(netElec.emission_ges.emission_ges_fr).toBeCloseTo(
|
|
320
|
+
brutElec.emission_ges.emission_ges_fr * 0.5,
|
|
321
|
+
9
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
const brutGaz = calc_conso(100, 1, 1, [], [], [], frGaz, 1, 1, DATE_DPE, coef_ep);
|
|
325
|
+
const netGaz = calc_conso(
|
|
326
|
+
100,
|
|
327
|
+
1,
|
|
328
|
+
1,
|
|
329
|
+
[],
|
|
330
|
+
[],
|
|
331
|
+
[],
|
|
332
|
+
frGaz,
|
|
333
|
+
1,
|
|
334
|
+
1,
|
|
335
|
+
DATE_DPE,
|
|
336
|
+
coef_ep,
|
|
337
|
+
1,
|
|
338
|
+
1,
|
|
339
|
+
facteursAc
|
|
340
|
+
);
|
|
341
|
+
expect(netGaz.emission_ges.emission_ges_fr).toBeGreaterThan(0);
|
|
342
|
+
expect(netGaz.emission_ges.emission_ges_fr).toBe(brutGaz.emission_ges.emission_ges_fr);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
test('sans facteurs d’autoconsommation : résultats identiques', () => {
|
|
346
|
+
const ch = [
|
|
347
|
+
installCh({ cle_repartition_ch: 1 }, [
|
|
348
|
+
genCh('1', { conso_ch: 1000, conso_ch_depensier: 1200 })
|
|
349
|
+
])
|
|
350
|
+
];
|
|
351
|
+
const brut = calc_conso(100, 1, 1, [], ch, [], [], 1, 1, DATE_DPE, coef_ep);
|
|
352
|
+
const net = calc_conso(100, 1, 1, [], ch, [], [], 1, 1, DATE_DPE, coef_ep, 1, 1, {});
|
|
353
|
+
expect(net).toStrictEqual(brut);
|
|
354
|
+
});
|
|
355
|
+
|
|
241
356
|
test('installation collective (méthode 2) : clé de répartition appliquée à conso et distribution', () => {
|
|
242
357
|
const ch = [
|
|
243
358
|
installCh(
|
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.43';
|
|
37
37
|
|
|
38
38
|
const dpeSanitizerService = new DpeSanitizerService();
|
|
39
39
|
|
|
@@ -617,6 +617,7 @@ export function calcul_3cl(inputDpe, options) {
|
|
|
617
617
|
cg.surface_habitable_immeuble
|
|
618
618
|
);
|
|
619
619
|
|
|
620
|
+
const facteursAc = {};
|
|
620
621
|
const production_electricite = productionENR.calculateEnr(
|
|
621
622
|
dpe.logement.production_elec_enr,
|
|
622
623
|
conso,
|
|
@@ -624,9 +625,35 @@ export function calcul_3cl(inputDpe, options) {
|
|
|
624
625
|
th,
|
|
625
626
|
zc_id,
|
|
626
627
|
undefined,
|
|
627
|
-
ratioPv
|
|
628
|
+
ratioPv,
|
|
629
|
+
facteursAc
|
|
628
630
|
);
|
|
629
631
|
|
|
632
|
+
/**
|
|
633
|
+
* Émissions GES et coût calculés sur les consommations électriques minorées de l'autoconsommation
|
|
634
|
+
* PV (Tribu `Calcul_batiment.cs` l.1188 carbone_total, l.1318 calc_cout.Calcul).
|
|
635
|
+
*/
|
|
636
|
+
if (Object.keys(facteursAc).length) {
|
|
637
|
+
const consoNette = calc_conso(
|
|
638
|
+
Sh,
|
|
639
|
+
zc_id,
|
|
640
|
+
ca_id,
|
|
641
|
+
vt_list,
|
|
642
|
+
instal_ch,
|
|
643
|
+
ecs,
|
|
644
|
+
clim,
|
|
645
|
+
prorataECS,
|
|
646
|
+
prorataChauffage,
|
|
647
|
+
dateDpe,
|
|
648
|
+
coef_ep,
|
|
649
|
+
th === 'immeuble' ? Nb_lgt : 1,
|
|
650
|
+
ratioSurfaceCoutCollectif,
|
|
651
|
+
facteursAc
|
|
652
|
+
);
|
|
653
|
+
conso.emission_ges = consoNette.emission_ges;
|
|
654
|
+
conso.cout = consoNette.cout;
|
|
655
|
+
}
|
|
656
|
+
|
|
630
657
|
const conso1_7 = calc_conso(
|
|
631
658
|
Sh,
|
|
632
659
|
zc_id,
|
package/engine.spec.js
CHANGED
|
@@ -444,7 +444,8 @@ describe('calcul_3cl - run intégral (maison)', () => {
|
|
|
444
444
|
'maison',
|
|
445
445
|
'zc1',
|
|
446
446
|
undefined,
|
|
447
|
-
0.25
|
|
447
|
+
0.25,
|
|
448
|
+
{}
|
|
448
449
|
]);
|
|
449
450
|
expect(calculateEnr.mock.calls[1][5]).toBe(1.7);
|
|
450
451
|
expect(calculateEnr.mock.calls[2][5]).toBe(2.3);
|
|
@@ -494,6 +495,29 @@ describe('calcul_3cl - run intégral (maison)', () => {
|
|
|
494
495
|
expect(calc_clim).toHaveBeenCalledTimes(1);
|
|
495
496
|
});
|
|
496
497
|
|
|
498
|
+
test('autoconsommation PV : GES et coût recalculés sur les consommations nettes (Tribu Calcul_batiment.cs l.1188 / l.1318)', () => {
|
|
499
|
+
const dpe = makeDpe();
|
|
500
|
+
const facteurs = { ch: 0.8 };
|
|
501
|
+
vi.mocked(calculateEnr).mockImplementationOnce((enr, conso, Sh, th, zc, coef, ratio, f) => {
|
|
502
|
+
Object.assign(f, facteurs);
|
|
503
|
+
return { pv: 1 };
|
|
504
|
+
});
|
|
505
|
+
const consoNette = {
|
|
506
|
+
...consoResult,
|
|
507
|
+
emission_ges: { emission_ges_5_usages: 1 },
|
|
508
|
+
cout: { cout_5_usages: 2 }
|
|
509
|
+
};
|
|
510
|
+
vi.mocked(calc_conso).mockReturnValueOnce(consoResult).mockReturnValueOnce(consoNette);
|
|
511
|
+
|
|
512
|
+
calcul_3cl(dpe, { sanitize: false });
|
|
513
|
+
|
|
514
|
+
expect(calc_conso).toHaveBeenCalledTimes(4);
|
|
515
|
+
expect(calc_conso.mock.calls[1][13]).toEqual(facteurs);
|
|
516
|
+
expect(calc_conso.mock.calls[1][10]).toEqual(calc_conso.mock.calls[0][10]);
|
|
517
|
+
expect(dpe.logement.sortie.emission_ges).toEqual({ emission_ges_5_usages: 1 });
|
|
518
|
+
expect(dpe.logement.sortie.cout).toEqual({ cout_5_usages: 2 });
|
|
519
|
+
});
|
|
520
|
+
|
|
497
521
|
test('bâtiment matériaux anciens => ilpa = 1 ; incohérence inertie => erreur loggée', () => {
|
|
498
522
|
const dpe = makeDpe();
|
|
499
523
|
dpe.logement.meteo.batiment_materiaux_anciens = 1;
|
|
@@ -579,6 +603,21 @@ describe('calcul_3cl - surfaces immeuble / appartement et prorata', () => {
|
|
|
579
603
|
expect(conso_aux_distribution_ecs.mock.calls[0][3]).toBe(200);
|
|
580
604
|
});
|
|
581
605
|
|
|
606
|
+
test('immeuble avec autoconsommation PV : conso nette calculée avec le nombre de logements', () => {
|
|
607
|
+
enums.methode_application_dpe_log = { 1: 'dpe immeuble collectif' };
|
|
608
|
+
const dpe = makeDpe();
|
|
609
|
+
vi.mocked(calculateEnr).mockImplementationOnce((enr, conso, Sh, th, zc, coef, ratio, f) => {
|
|
610
|
+
Object.assign(f, { ch: 0.8 });
|
|
611
|
+
return { pv: 1 };
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
calcul_3cl(dpe, { sanitize: false });
|
|
615
|
+
|
|
616
|
+
// Nombre de logements de l'immeuble (nombre_appartement = 4) pour le recalcul net.
|
|
617
|
+
expect(calc_conso.mock.calls[1][11]).toBe(4);
|
|
618
|
+
expect(calc_conso.mock.calls[1][13]).toEqual({ ch: 0.8 });
|
|
619
|
+
});
|
|
620
|
+
|
|
582
621
|
test('immeuble : systèmes ECS non tous individuels sans surfaces => repli sur la division par deux', () => {
|
|
583
622
|
enums.methode_application_dpe_log = { 1: 'dpe immeuble collectif' };
|
|
584
623
|
const dpe = makeDpe();
|