@open3cl/engine 1.11.2 → 1.11.4
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 +1 -1
- package/10_clim.js +1 -1
- package/10_clim.spec.js +5 -9
- package/11_besoin_ecs.spec.js +1 -1
- package/11_ecs.js +2 -1
- package/11_ecs.spec.js +2 -2
- package/11_nadeq.js +1 -0
- package/11_nadeq.spec.js +1 -1
- package/11_rdim_ecs_individuelle_unique.js +78 -0
- package/11_rdim_ecs_individuelle_unique.spec.js +136 -0
- package/12.4_pac.js +5 -3
- package/12.4_pac.spec.js +10 -18
- package/13.2_generateur_combustion.js +19 -16
- package/13.2_generateur_combustion.spec.js +10 -10
- package/13.2_generateur_combustion_bouilleur.js +5 -2
- package/13.2_generateur_combustion_bouilleur.spec.js +1 -1
- package/13.2_generateur_combustion_ch.js +8 -7
- package/13.2_generateur_combustion_ch.spec.js +7 -7
- package/13.2_generateur_combustion_chaudiere.js +5 -2
- package/13.2_generateur_combustion_chaudiere.spec.js +2 -2
- package/13.2_generateur_combustion_pdim.js +6 -6
- package/13.2_generateur_combustion_pdim.spec.js +1 -1
- package/13.2_generateur_combustion_pn.spec.js +1 -1
- package/13.2_generateur_pac.js +4 -1
- package/13.2_generateur_pac.spec.js +1 -1
- package/13_rendement_distribution_ecs.spec.js +1 -1
- package/14_generateur_ecs.js +2 -1
- package/14_generateur_ecs.spec.js +4 -4
- package/15_conso_aux.js +19 -17
- package/15_conso_aux.spec.js +8 -8
- package/16.2_production_enr.js +4 -3
- package/16.2_production_enr.spec.js +1 -1
- package/16_conso_eclairage.spec.js +1 -1
- package/2021_04_13_confort_ete.spec.js +1 -1
- package/2021_04_13_qualite_isolation.js +1 -1
- package/2021_04_13_qualite_isolation.spec.js +2 -2
- package/3.1_b.spec.js +1 -1
- package/3.2.1_mur.js +10 -9
- package/3.2.1_mur.spec.js +11 -19
- package/3.2.2_plancher_bas.js +4 -3
- package/3.2.2_plancher_bas.spec.js +10 -20
- package/3.2.3_plancher_haut.js +1 -1
- package/3.2.3_plancher_haut.spec.js +2 -2
- package/3.3.1.4_porte.js +1 -1
- package/3.3.1.4_porte.spec.js +2 -2
- package/3.3_baie_vitree.js +2 -2
- package/3.3_baie_vitree.spec.js +3 -3
- package/3.4_pont_thermique.js +6 -4
- package/3.4_pont_thermique.spec.js +7 -7
- package/3_deperdition.js +1 -0
- package/3_deperdition.spec.js +3 -3
- package/4_ventilation.js +2 -2
- package/4_ventilation.spec.js +1 -1
- package/5_conso_ventilation.spec.js +1 -1
- package/6.1_apport_gratuit.spec.js +2 -2
- package/6.2_surface_sud_equivalente.js +12 -9
- package/6.2_surface_sud_equivalente.spec.js +3 -3
- package/7_inertie.js +7 -4
- package/7_inertie.spec.js +1 -1
- package/8_intermittence.spec.js +1 -1
- package/9_besoin_ch.js +5 -3
- package/9_besoin_ch.spec.js +3 -3
- package/9_chauffage.js +12 -11
- package/9_chauffage.spec.js +7 -7
- package/9_conso_ch.spec.js +3 -3
- package/9_emetteur_ch.js +5 -5
- package/9_emetteur_ch.spec.js +1 -1
- package/9_generateur_ch.js +16 -13
- package/9_generateur_ch.spec.js +6 -6
- package/README.md +19 -19
- package/apport_et_besoin.spec.js +1 -1
- package/conso.js +18 -14
- package/conso.spec.js +3 -3
- package/core/assets/domain/synchronize-assets.js +2 -0
- package/core/assets/domain/synchronize-c1-tables.js +2 -0
- package/core/assets/domain/synchronize-dpe-ges-limit-values-tables.js +2 -0
- package/core/assets/domain/synchronize-enum-tables.js +2 -0
- package/core/assets/domain/synchronize-solicitations-tables.js +2 -0
- package/core/assets/domain/synchronize-valeur-tables.js +6 -0
- package/core/file/infrastructure/adapter/csv-parser.store.js +2 -1
- package/dpe-sanitizer.service.js +1 -0
- package/engine.js +11 -2
- package/engine.spec.js +23 -2
- package/enums.d.ts +1257 -0
- package/features/dpe/domain/models/baie-ets.model.ts +8 -11
- package/features/dpe/domain/models/baie-vitree.model.ts +28 -96
- package/features/dpe/domain/models/climatisation.model.ts +13 -23
- package/features/dpe/domain/models/dpe-xsd.generated.ts +2797 -0
- package/features/dpe/domain/models/dpe.model.ts +105 -181
- package/features/dpe/domain/models/ets.model.ts +10 -18
- package/features/dpe/domain/models/installation-chauffage.model.ts +92 -99
- package/features/dpe/domain/models/installation-ecs.model.ts +45 -77
- package/features/dpe/domain/models/mur.model.ts +10 -38
- package/features/dpe/domain/models/plancher.model.ts +22 -63
- package/features/dpe/domain/models/pont-thermique.model.ts +10 -20
- package/features/dpe/domain/models/porte.model.ts +10 -30
- package/features/dpe/domain/models/production-elec-enr.model.ts +13 -27
- package/features/dpe/domain/models/sortie.model.ts +32 -176
- package/features/dpe/domain/models/type-generateur.model.js +4 -3
- package/features/dpe/domain/models/type-habitation.model.js +8 -6
- package/features/dpe/domain/models/type-stockage.model.js +4 -3
- package/features/dpe/domain/models/type-ventilation.model.js +4 -3
- package/features/dpe/domain/models/ventilation.model.ts +15 -25
- package/features/dpe/infrastructure/ch/chTv.store.js +2 -2
- package/features/dpe/infrastructure/ecs/ecsTv.store.js +3 -3
- package/features/dpe/infrastructure/enveloppe/baieVitreeTv.store.js +1 -1
- package/features/dpe/infrastructure/froid/frTv.store.js +3 -3
- package/features/dpe/infrastructure/froid/frTv.store.spec.js +1 -1
- package/features/dpe/infrastructure/tv.store.js +1 -1
- package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.js +3 -0
- package/features/engine/domain/apport_et_besoin/apport_gratuit/apport-gratuit.service.js +3 -1
- package/features/engine/domain/apport_et_besoin/ch/besoin-ch.service.js +3 -1
- package/features/engine/domain/apport_et_besoin/ch/perte-ch-recup.service.js +9 -3
- package/features/engine/domain/apport_et_besoin/ch/perte-ch-recup.service.spec.js +1 -1
- package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.js +2 -1
- package/features/engine/domain/apport_et_besoin/ecs/perte-ecs-recup.service.js +4 -1
- package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.js +3 -1
- package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.js +7 -2
- package/features/engine/domain/apport_et_besoin/surface-sud-equivalente.service.spec.js +1 -1
- package/features/engine/domain/ch/emetteur-ch.service.js +3 -1
- package/features/engine/domain/ch/emetteur-ch.service.spec.js +1 -1
- package/features/engine/domain/ch/generateur-ch.service.js +4 -1
- package/features/engine/domain/ch/generateur-ch.service.spec.js +3 -3
- package/features/engine/domain/ch/installation-ch.service.js +2 -0
- package/features/engine/domain/conso/conso.service.js +2 -0
- package/features/engine/domain/conso/froid/conso-froid.service.js +5 -1
- package/features/engine/domain/contexte.builder.js +2 -0
- package/features/engine/domain/ecs/generateur-ecs.service.js +1 -0
- package/features/engine/domain/ecs/installation-ecs.service.js +3 -0
- package/features/engine/domain/engine.service.js +1 -0
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.js +4 -1
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.js +3 -0
- package/features/engine/domain/enveloppe/deperdition.service.js +8 -4
- package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.js +4 -1
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.js +3 -1
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.js +3 -1
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +2 -2
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.js +4 -2
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.js +9 -1
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +1 -1
- package/features/engine/domain/enveloppe/porte/deperdition-porte.service.js +3 -1
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.js +3 -1
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +1 -1
- package/features/engine/domain/logement/nadeq.service.js +1 -1
- package/features/engine/domain/logement/nadeq.service.spec.js +1 -1
- package/features/engine/domain/models/contexte.model.ts +2 -2
- package/features/normalizer/domain/dpe-normalizer.service.js +1 -0
- package/ficheTechnique.js +4 -2
- package/globals.d.ts +14 -0
- package/package.json +3 -2
- package/preprocessor/index.js +1 -0
- package/tv.d.ts +759 -0
- package/tvs.d.ts +2 -7
- package/utils.js +8 -6
package/10_besoin_fr.spec.js
CHANGED
|
@@ -38,7 +38,7 @@ const { calc_sse_j } = await import('./6.2_surface_sud_equivalente.js');
|
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* 10. Calcul des besoins de froid (Bfr)
|
|
41
|
-
* @see
|
|
41
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §10
|
|
42
42
|
*/
|
|
43
43
|
describe('calc_besoin_fr_j - besoin de froid journalier', () => {
|
|
44
44
|
test('retourne 0 lorsque le nombre de jours de référence est nul', () => {
|
package/10_clim.js
CHANGED
|
@@ -5,7 +5,7 @@ function tv_seer(di, de, du, zc_id) {
|
|
|
5
5
|
enum_zone_climatique_id: zc_id,
|
|
6
6
|
enum_periode_installation_fr_id: requestInputID(de, du, 'periode_installation_fr')
|
|
7
7
|
};
|
|
8
|
-
const row = tv('seer', matcher
|
|
8
|
+
const row = tv('seer', matcher);
|
|
9
9
|
if (row) {
|
|
10
10
|
de.tv_seer_id = Number(row.tv_seer_id);
|
|
11
11
|
di.eer = row.eer;
|
package/10_clim.spec.js
CHANGED
|
@@ -31,7 +31,7 @@ beforeEach(() => {
|
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* 10. Calcul de la consommation de climatisation (froid)
|
|
34
|
-
* @see
|
|
34
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §10
|
|
35
35
|
*/
|
|
36
36
|
describe('calc_clim - consommation de climatisation', () => {
|
|
37
37
|
test('prorate le besoin de froid au ratio surface_clim / Sh', () => {
|
|
@@ -69,14 +69,10 @@ describe('calc_clim - consommation de climatisation', () => {
|
|
|
69
69
|
|
|
70
70
|
calc_clim(c, 1000, 1500, '2', 100);
|
|
71
71
|
|
|
72
|
-
expect(tv).toHaveBeenCalledWith(
|
|
73
|
-
'
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
enum_periode_installation_fr_id: '4'
|
|
77
|
-
},
|
|
78
|
-
c.donnee_entree
|
|
79
|
-
);
|
|
72
|
+
expect(tv).toHaveBeenCalledWith('seer', {
|
|
73
|
+
enum_zone_climatique_id: '2',
|
|
74
|
+
enum_periode_installation_fr_id: '4'
|
|
75
|
+
});
|
|
80
76
|
});
|
|
81
77
|
|
|
82
78
|
test.each([['6'], ['7'], ['8']])(
|
package/11_besoin_ecs.spec.js
CHANGED
|
@@ -23,7 +23,7 @@ const { default: calc_besoin_ecs, calc_besoin_ecs_j } = await import('./11_besoi
|
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* 11. Calcul du besoin d'eau chaude sanitaire (Becs)
|
|
26
|
-
* @see
|
|
26
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §11
|
|
27
27
|
*/
|
|
28
28
|
describe('calc_besoin_ecs_j - besoin ECS journalier', () => {
|
|
29
29
|
test('valeur de référence en mode conventionnel (56 L/j/personne)', () => {
|
package/11_ecs.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** @import { InstallationEcsDE } from './features/dpe/domain/models/installation-ecs.model.js' */
|
|
1
2
|
import enums from './enums.js';
|
|
2
3
|
import calc_gen_ecs from './14_generateur_ecs.js';
|
|
3
4
|
import { tv, requestInput, mois_liste, Njj } from './utils.js';
|
|
@@ -196,7 +197,7 @@ const TYPES_INSTALLATION_ECS_COLLECTIVE = ['2', '3'];
|
|
|
196
197
|
* @see Moteur_DPE.dll Calcul_batiment.cs l.583-592 (Becs / Rdim seulement pour une installation
|
|
197
198
|
* individuelle en immeuble ; Becs × Sh_ecs / SH sans Rdim pour une installation collective)
|
|
198
199
|
* @param th {string} type de bâtiment (maison, appartement, immeuble)
|
|
199
|
-
* @param de {
|
|
200
|
+
* @param de {InstallationEcsDE} donnée d'entrée de l'installation ECS
|
|
200
201
|
* @returns {boolean}
|
|
201
202
|
*/
|
|
202
203
|
export function isRdimEcsNeutralise(th, de) {
|
package/11_ecs.spec.js
CHANGED
|
@@ -61,7 +61,7 @@ beforeEach(() => {
|
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
63
|
* 11. Prise en compte de l'ECS (ratio de besoin + rendement de distribution)
|
|
64
|
-
* @see
|
|
64
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §11 / §17.2.1
|
|
65
65
|
*/
|
|
66
66
|
describe('calc_ecs - ratio de besoin ECS', () => {
|
|
67
67
|
test('virtualisation : le ratio est la clé de répartition ECS', () => {
|
|
@@ -87,7 +87,7 @@ describe('calc_ecs - ratio de besoin ECS', () => {
|
|
|
87
87
|
* Immeuble à ECS individuelles de surfaces différentes (cas CSTB IC1-0-3 / IC1-0-5 : 4
|
|
88
88
|
* appartements de 20, 30, 45 et 80 m² sur 175 m², rdim 1) : besoin au prorata de la surface
|
|
89
89
|
* desservie, comme Tribu (Becs appartement 1 = Becs immeuble × 20 / 175).
|
|
90
|
-
* @see
|
|
90
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §11.4
|
|
91
91
|
*/
|
|
92
92
|
test('immeuble à ECS individuelles : ratio = surface desservie / surface de l’immeuble', () => {
|
|
93
93
|
const des = [20, 30, 45, 80].map((surface) => ({
|
package/11_nadeq.js
CHANGED
package/11_nadeq.spec.js
CHANGED
|
@@ -60,3 +60,81 @@ export function reconstituerRdimEcsIndividuelleUnique(th, instal_ecs, surfaceHab
|
|
|
60
60
|
instal_ecs[0].donnee_entree.rdim_reconstitue = true;
|
|
61
61
|
return true;
|
|
62
62
|
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* DPE immeuble avec plusieurs installations ECS individuelles, chacune décrite pour un logement type.
|
|
66
|
+
*
|
|
67
|
+
* Même convention d'export que l'installation unique (3.0.x, 2.0.x, 1.1.x) : pour chaque
|
|
68
|
+
* installation i, `surface_habitable` = Sh_i d'un logement type et `nombre_logement` = N_i, sans
|
|
69
|
+
* `rdim`, avec Σ Sh_i × N_i = SH. Tribu traite chaque installation indépendamment avec Rdim_i = N_i :
|
|
70
|
+
* Becs_i = Becs_immeuble × Sh_i × Rdim_i / SH / Rdim_i, puis Cecs = Σ Cecs_i × Rdim_i. L'export ADEME
|
|
71
|
+
* le confirme : besoin_ecs_i = Becs_immeuble × Sh_i / SH et conso_ecs = Σ conso_ecs_i × N_i.
|
|
72
|
+
*
|
|
73
|
+
* Sans rdim, Σ Sh_i ≠ SH : Open3CL se replie sur Becs_immeuble / nombre_appartement par
|
|
74
|
+
* installation et ne remultiplie pas la conso par N_i.
|
|
75
|
+
*
|
|
76
|
+
* Gardes :
|
|
77
|
+
* - Σ Sh_i × N_i ≈ SH (TOLERANCE_SURFACE_LOGEMENT_TYPE) : exclut les exports où Sh_i est déjà
|
|
78
|
+
* la surface totale desservie (Σ Sh_i = SH, ex. N_i fractionnaires) ;
|
|
79
|
+
* - au moins un N_i > 1 : sinon rdim = 1 partout, sans effet (LICIEL, nombre_logement = 1).
|
|
80
|
+
*
|
|
81
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - § 11.4 et § 17.1.3.2
|
|
82
|
+
* @see Tribu : Calcul_batiment.cs l. 581-588 (boucle par installation, Ratio = Sh·Rdim/SH,
|
|
83
|
+
* Becs / Rdim), l. 1660-1662 (Cecs_i / Rdim puis × Rdim) ; Calcul_installation_ECS.cs l. 75
|
|
84
|
+
* @see Guide Tribu TE-211208 « Particularités d'une répétition de systèmes d'ECS individuel dans un
|
|
85
|
+
* immeuble collectif » (Sh_ecs = surface d'un logement, Rdim = nombre d'installations identiques)
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Rdim implicites des installations ECS individuelles multiples d'un immeuble (dans l'ordre des
|
|
90
|
+
* installations), ou null si non concernées.
|
|
91
|
+
*
|
|
92
|
+
* @param th {string} type de bâtiment (maison, appartement, immeuble)
|
|
93
|
+
* @param instal_ecs {Array} installation_ecs
|
|
94
|
+
* @param surfaceHabitableImmeuble {number|string} surface habitable de l'immeuble (SH)
|
|
95
|
+
* @return {number[]|null}
|
|
96
|
+
*/
|
|
97
|
+
export function rdimsImplicitesEcsIndividuellesMultiples(th, instal_ecs, surfaceHabitableImmeuble) {
|
|
98
|
+
if (th !== 'immeuble' || !Array.isArray(instal_ecs) || instal_ecs.length < 2) return null;
|
|
99
|
+
|
|
100
|
+
const des = instal_ecs.map((inst) => inst?.donnee_entree);
|
|
101
|
+
const concernees = des.every(
|
|
102
|
+
(de) => de && String(de.enum_type_installation_id) === '1' && !de.rdim
|
|
103
|
+
);
|
|
104
|
+
if (!concernees) return null;
|
|
105
|
+
|
|
106
|
+
const SH = Number(surfaceHabitableImmeuble);
|
|
107
|
+
if (!(SH > 0)) return null;
|
|
108
|
+
|
|
109
|
+
const surfaces = des.map((de) => Number(de.surface_habitable));
|
|
110
|
+
const rdims = des.map((de) => Number(de.nombre_logement) || 1);
|
|
111
|
+
if (!surfaces.every((sh) => sh > 0) || !rdims.every((n) => n > 0)) return null;
|
|
112
|
+
if (!rdims.some((n) => n > 1)) return null;
|
|
113
|
+
|
|
114
|
+
const sommeShN = surfaces.reduce((acc, sh, i) => acc + sh * rdims[i], 0);
|
|
115
|
+
return Math.abs(sommeShN - SH) <= TOLERANCE_SURFACE_LOGEMENT_TYPE * SH ? rdims : null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Reconstitue le rdim des installations ECS individuelles multiples d'un immeuble décrites pour un
|
|
120
|
+
* logement type. Chaque installation reçoit `rdim` = nombre_logement (1 si absent) et le flag
|
|
121
|
+
* `rdim_reconstitue`.
|
|
122
|
+
*
|
|
123
|
+
* @param th {string} type de bâtiment
|
|
124
|
+
* @param instal_ecs {Array} installation_ecs
|
|
125
|
+
* @param surfaceHabitableImmeuble {number|string} surface habitable de l'immeuble (SH)
|
|
126
|
+
* @return {boolean} true si les rdim ont été reconstitués
|
|
127
|
+
*/
|
|
128
|
+
export function reconstituerRdimEcsIndividuellesMultiples(
|
|
129
|
+
th,
|
|
130
|
+
instal_ecs,
|
|
131
|
+
surfaceHabitableImmeuble
|
|
132
|
+
) {
|
|
133
|
+
const rdims = rdimsImplicitesEcsIndividuellesMultiples(th, instal_ecs, surfaceHabitableImmeuble);
|
|
134
|
+
if (rdims === null) return false;
|
|
135
|
+
instal_ecs.forEach((inst, i) => {
|
|
136
|
+
inst.donnee_entree.rdim = rdims[i];
|
|
137
|
+
inst.donnee_entree.rdim_reconstitue = true;
|
|
138
|
+
});
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vitest';
|
|
2
2
|
import {
|
|
3
3
|
rdimImpliciteEcsIndividuelleUnique,
|
|
4
|
+
rdimsImplicitesEcsIndividuellesMultiples,
|
|
4
5
|
reconstituerRdimEcsIndividuelleUnique,
|
|
6
|
+
reconstituerRdimEcsIndividuellesMultiples,
|
|
5
7
|
TOLERANCE_SURFACE_LOGEMENT_TYPE
|
|
6
8
|
} from './11_rdim_ecs_individuelle_unique.js';
|
|
7
9
|
|
|
@@ -111,3 +113,137 @@ describe("Rdim de l'installation ECS individuelle unique d'un immeuble", () => {
|
|
|
111
113
|
});
|
|
112
114
|
});
|
|
113
115
|
});
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - § 11.4 et § 17.1.3.2
|
|
119
|
+
* @see Tribu : Calcul_batiment.cs l. 581-588 et l. 1660-1662 ; Calcul_installation_ECS.cs l. 75
|
|
120
|
+
*/
|
|
121
|
+
describe("Rdim des installations ECS individuelles multiples d'un immeuble", () => {
|
|
122
|
+
/** Installation ECS individuelle décrite pour un logement type */
|
|
123
|
+
const inst = (surface_habitable, nombre_logement, de = {}) => ({
|
|
124
|
+
donnee_entree: { enum_type_installation_id: '1', surface_habitable, nombre_logement, ...de }
|
|
125
|
+
});
|
|
126
|
+
/** Cas type 2244E3039157K : 48,82 × 2 + 78,09 × 6 = 566,18 ≈ SH = 566,16 */
|
|
127
|
+
const ecs = () => [inst(48.82, 2), inst(78.09, 6)];
|
|
128
|
+
|
|
129
|
+
describe('rdimsImplicitesEcsIndividuellesMultiples', () => {
|
|
130
|
+
test('installations individuelles, Σ Sh × N = SH, sans rdim : rdim_i = nombre_logement_i', () => {
|
|
131
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', ecs(), 566.16)).toEqual([2, 6]);
|
|
132
|
+
expect(
|
|
133
|
+
rdimsImplicitesEcsIndividuellesMultiples(
|
|
134
|
+
'immeuble',
|
|
135
|
+
[
|
|
136
|
+
inst('48.82', '2', { enum_type_installation_id: 1 }),
|
|
137
|
+
inst('78.09', '6', { enum_type_installation_id: 1 })
|
|
138
|
+
],
|
|
139
|
+
'566.16'
|
|
140
|
+
)
|
|
141
|
+
).toEqual([2, 6]);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('nombre_logement absent sur une installation : rdim = 1 pour celle-ci', () => {
|
|
145
|
+
// 100 × 4 + 50 × 1 = 450
|
|
146
|
+
expect(
|
|
147
|
+
rdimsImplicitesEcsIndividuellesMultiples(
|
|
148
|
+
'immeuble',
|
|
149
|
+
[inst(100, 4), inst(50, undefined)],
|
|
150
|
+
450
|
|
151
|
+
)
|
|
152
|
+
).toEqual([4, 1]);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('tolérance de 5 % sur Σ Sh × N ≈ SH', () => {
|
|
156
|
+
// Σ = 100 × 4 + 50 × 2 = 500 ; |500 − SH| ≤ 0,05 × SH ⇔ 476,19 ≤ SH ≤ 526,31
|
|
157
|
+
const deux = () => [inst(100, 4), inst(50, 2)];
|
|
158
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 526)).toEqual([4, 2]);
|
|
159
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 477)).toEqual([4, 2]);
|
|
160
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 527)).toBeNull();
|
|
161
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 476)).toBeNull();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('surfaces exportées comme surface totale desservie (Σ Sh = SH) : non concerné', () => {
|
|
165
|
+
// Cas type 2224E1374434V : 74,4 × 3 + 31 × 1 = 254,2 ≠ SH = 105,4 = Σ Sh
|
|
166
|
+
expect(
|
|
167
|
+
rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(74.4, 3), inst(31, 1)], 105.4)
|
|
168
|
+
).toBeNull();
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('tous les nombre_logement à 1 (LICIEL) : non concerné', () => {
|
|
172
|
+
expect(
|
|
173
|
+
rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(60, 1), inst(40, 1)], 100)
|
|
174
|
+
).toBeNull();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('un rdim exporté sur une installation : on conserve la saisie', () => {
|
|
178
|
+
expect(
|
|
179
|
+
rdimsImplicitesEcsIndividuellesMultiples(
|
|
180
|
+
'immeuble',
|
|
181
|
+
[inst(48.82, 2, { rdim: 2 }), inst(78.09, 6)],
|
|
182
|
+
566.16
|
|
183
|
+
)
|
|
184
|
+
).toBeNull();
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test('une installation collective : non concerné', () => {
|
|
188
|
+
expect(
|
|
189
|
+
rdimsImplicitesEcsIndividuellesMultiples(
|
|
190
|
+
'immeuble',
|
|
191
|
+
[inst(48.82, 2), inst(78.09, 6, { enum_type_installation_id: '2' })],
|
|
192
|
+
566.16
|
|
193
|
+
)
|
|
194
|
+
).toBeNull();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test('maison ou appartement : non concerné', () => {
|
|
198
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('maison', ecs(), 566.16)).toBeNull();
|
|
199
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('appartement', ecs(), 566.16)).toBeNull();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test('installation unique : non concerné (cf. rdimImpliciteEcsIndividuelleUnique)', () => {
|
|
203
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(64, 10)], 640)).toBeNull();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test('données manquantes ou invalides : non concerné', () => {
|
|
207
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', undefined, 566.16)).toBeNull();
|
|
208
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', [], 566.16)).toBeNull();
|
|
209
|
+
expect(
|
|
210
|
+
rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(48.82, 2), {}], 566.16)
|
|
211
|
+
).toBeNull();
|
|
212
|
+
expect(
|
|
213
|
+
rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(48.82, 2), null], 566.16)
|
|
214
|
+
).toBeNull();
|
|
215
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', ecs(), undefined)).toBeNull();
|
|
216
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', ecs(), 0)).toBeNull();
|
|
217
|
+
expect(
|
|
218
|
+
rdimsImplicitesEcsIndividuellesMultiples(
|
|
219
|
+
'immeuble',
|
|
220
|
+
[inst(48.82, 2), inst(undefined, 6)],
|
|
221
|
+
566.16
|
|
222
|
+
)
|
|
223
|
+
).toBeNull();
|
|
224
|
+
expect(
|
|
225
|
+
rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(100, 4), inst(50, -2)], 300)
|
|
226
|
+
).toBeNull();
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
describe('reconstituerRdimEcsIndividuellesMultiples', () => {
|
|
231
|
+
test('installations concernées : rdim et flag positionnés sur chacune', () => {
|
|
232
|
+
const installations = ecs();
|
|
233
|
+
expect(reconstituerRdimEcsIndividuellesMultiples('immeuble', installations, 566.16)).toBe(
|
|
234
|
+
true
|
|
235
|
+
);
|
|
236
|
+
expect(installations[0].donnee_entree).toMatchObject({ rdim: 2, rdim_reconstitue: true });
|
|
237
|
+
expect(installations[1].donnee_entree).toMatchObject({ rdim: 6, rdim_reconstitue: true });
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test('installations non concernées : inchangées', () => {
|
|
241
|
+
const installations = [inst(60, 1), inst(40, 1)];
|
|
242
|
+
expect(reconstituerRdimEcsIndividuellesMultiples('immeuble', installations, 100)).toBe(false);
|
|
243
|
+
installations.forEach((i) => {
|
|
244
|
+
expect(i.donnee_entree.rdim).toBeUndefined();
|
|
245
|
+
expect(i.donnee_entree.rdim_reconstitue).toBeUndefined();
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
});
|
package/12.4_pac.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
/** @import { GenerateurChauffageDE, GenerateurChauffageDI } from './features/dpe/domain/models/installation-chauffage.model.js' */
|
|
2
|
+
/** @import { GenerateurEcsDE, GenerateurEcsDI } from './features/dpe/domain/models/installation-ecs.model.js' */
|
|
1
3
|
import { requestInputID, tv } from './utils.js';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* Calcul ou récupération des paramètres scop ou cop
|
|
5
|
-
* @param di {
|
|
6
|
-
* @param de {
|
|
7
|
+
* @param di {GenerateurChauffageDI|GenerateurEcsDI}
|
|
8
|
+
* @param de {GenerateurChauffageDE|GenerateurEcsDE}
|
|
7
9
|
* @param du {Object}
|
|
8
10
|
* @param zc_id {string}
|
|
9
11
|
* @param ed_id {string|null}
|
|
@@ -31,7 +33,7 @@ function tv_scop(di, de, du, zc_id, ed_id, type) {
|
|
|
31
33
|
};
|
|
32
34
|
matcher[`enum_type_generateur_${type}_id`] = requestInputID(de, du, `type_generateur_${type}`);
|
|
33
35
|
if (ed_id) matcher.enum_type_emission_distribution_id = ed_id;
|
|
34
|
-
const row = tv('scop', matcher
|
|
36
|
+
const row = tv('scop', matcher);
|
|
35
37
|
if (row) {
|
|
36
38
|
const scop = row.scop_ou_cop;
|
|
37
39
|
di[scop] = Number(row.scop);
|
package/12.4_pac.spec.js
CHANGED
|
@@ -26,7 +26,7 @@ beforeEach(() => {
|
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* 12.4 - Détermination du SCOP / COP des pompes à chaleur.
|
|
29
|
-
* @see
|
|
29
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §12.4
|
|
30
30
|
*/
|
|
31
31
|
describe('scopOrCop - méthode de saisie "caractéristiques saisies" (id 6)', () => {
|
|
32
32
|
test('SCOP renseigné : rg et rg_dep prennent la valeur du SCOP sans accès à la table', () => {
|
|
@@ -55,14 +55,10 @@ describe('scopOrCop - valeur forfaitaire (table scop)', () => {
|
|
|
55
55
|
|
|
56
56
|
scopOrCop(di, de, {}, 'h1a', null, 'ch');
|
|
57
57
|
|
|
58
|
-
expect(tv).toHaveBeenCalledWith(
|
|
59
|
-
'
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
enum_type_generateur_ch_id: '160'
|
|
63
|
-
},
|
|
64
|
-
de
|
|
65
|
-
);
|
|
58
|
+
expect(tv).toHaveBeenCalledWith('scop', {
|
|
59
|
+
enum_zone_climatique_id: 'h1a',
|
|
60
|
+
enum_type_generateur_ch_id: '160'
|
|
61
|
+
});
|
|
66
62
|
expect(di.scop).toBe(4.2);
|
|
67
63
|
expect(di.rg).toBe(4.2);
|
|
68
64
|
expect(di.rg_dep).toBe(4.2);
|
|
@@ -76,15 +72,11 @@ describe('scopOrCop - valeur forfaitaire (table scop)', () => {
|
|
|
76
72
|
|
|
77
73
|
scopOrCop(di, de, {}, 'h2b', '5', 'ecs');
|
|
78
74
|
|
|
79
|
-
expect(tv).toHaveBeenCalledWith(
|
|
80
|
-
'
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
enum_type_emission_distribution_id: '5'
|
|
85
|
-
},
|
|
86
|
-
de
|
|
87
|
-
);
|
|
75
|
+
expect(tv).toHaveBeenCalledWith('scop', {
|
|
76
|
+
enum_zone_climatique_id: 'h2b',
|
|
77
|
+
enum_type_generateur_ecs_id: '10',
|
|
78
|
+
enum_type_emission_distribution_id: '5'
|
|
79
|
+
});
|
|
88
80
|
// scop_ou_cop vaut 'cop' : la valeur est stockée sous di.cop
|
|
89
81
|
expect(di.cop).toBe(3.1);
|
|
90
82
|
expect(di.rg).toBe(3.1);
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/** @import { FullDpe } from './features/dpe/domain/models/dpe.model.js' */
|
|
2
|
+
/** @import { GenerateurChauffage, GenerateurChauffageDE, GenerateurChauffageDI, InstallationChauffage } from './features/dpe/domain/models/installation-chauffage.model.js' */
|
|
3
|
+
/** @import { GenerateurEcsDE, GenerateurEcsDI } from './features/dpe/domain/models/installation-ecs.model.js' */
|
|
1
4
|
import { bug_for_bug_compat, convertExpression, tv, tvColumnLines } from './utils.js';
|
|
2
5
|
import enums from './enums.js';
|
|
3
6
|
import { updateGenerateurBouilleurs } from './13.2_generateur_combustion_bouilleur.js';
|
|
@@ -63,7 +66,7 @@ export const PN_MAX_QP0_CHAUDIERE_GAZ = 400000;
|
|
|
63
66
|
* (Tribu, `Calcul_generateur.cs` Rpn_chaudieregaz, `Math.Min(400.0, Pn)`) plafonne Pn à 400 kW :
|
|
64
67
|
* au-delà, la formule n'est plus représentative (elle décroît et devient négative vers 1 500 kW).
|
|
65
68
|
* Le plafond ne s'applique pas aux chaudières fioul (Rpn_chaudierefioul : Pn non plafonné).
|
|
66
|
-
* @see
|
|
69
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
|
|
67
70
|
*
|
|
68
71
|
* @param row {object} ligne de la table generateur_combustion
|
|
69
72
|
* @param pnCollectif {number} puissance nominale du générateur (W)
|
|
@@ -154,7 +157,7 @@ export function pnEstimee(GV, tbase, ratioSurface = 1) {
|
|
|
154
157
|
* pour le chauffage, 8 pour l'ECS) du générateur.
|
|
155
158
|
*
|
|
156
159
|
* @param dpe {FullDpe}
|
|
157
|
-
* @param de {
|
|
160
|
+
* @param de {GenerateurChauffageDE|GenerateurEcsDE}
|
|
158
161
|
* @param type {'ch' | 'ecs'}
|
|
159
162
|
* @returns {boolean|undefined} undefined si non renseigné
|
|
160
163
|
*/
|
|
@@ -170,7 +173,7 @@ export function chaudiereMurale(dpe, de, type) {
|
|
|
170
173
|
* générateur ECS mixte de même `reference_generateur_mixte`, sinon générateur ECS mixte unique.
|
|
171
174
|
*
|
|
172
175
|
* @param dpe {FullDpe}
|
|
173
|
-
* @param de {
|
|
176
|
+
* @param de {GenerateurChauffageDE|GenerateurEcsDE} données du générateur de chauffage
|
|
174
177
|
* @returns {number|undefined}
|
|
175
178
|
*/
|
|
176
179
|
export function volumeStockageEcsMixte(dpe, de) {
|
|
@@ -200,7 +203,7 @@ export function volumeStockageEcsMixte(dpe, de) {
|
|
|
200
203
|
* pour une installation collective, Pch est conservée (comportement historique).
|
|
201
204
|
*
|
|
202
205
|
* @param dpe {FullDpe}
|
|
203
|
-
* @param de {
|
|
206
|
+
* @param de {GenerateurChauffageDE|GenerateurEcsDE} données du générateur
|
|
204
207
|
* @param type {'ch' | 'ecs'}
|
|
205
208
|
* @param pch {number} Pch (W) proratisée à la surface desservie
|
|
206
209
|
* @param optionsPn {{installationIndividuelle?: boolean, volumeStockage?: number}}
|
|
@@ -249,8 +252,8 @@ export function pnEstimeeGenerateur(dpe, de, type, pch, optionsPn = {}) {
|
|
|
249
252
|
* 5 - caractéristiques saisies à partir de la plaque signalétique ou d'une documentation technique du système à combustion : pn, rpn,rpint,qp0,temp_fonc_30,temp_fonc_100
|
|
250
253
|
*
|
|
251
254
|
* @param dpe {FullDpe}
|
|
252
|
-
* @param di {
|
|
253
|
-
* @param de {
|
|
255
|
+
* @param di {GenerateurChauffageDI|GenerateurEcsDI} données du générateur
|
|
256
|
+
* @param de {GenerateurChauffageDE|GenerateurEcsDE} données du générateur
|
|
254
257
|
* @param type {'ecs'|'ch'}
|
|
255
258
|
* @param GV {number} déperdition de l'enveloppe
|
|
256
259
|
* @param tbase {number} température de fonctionnement du générateur
|
|
@@ -392,8 +395,8 @@ export function tv_generateur_combustion(
|
|
|
392
395
|
* dans Cper). Le XML ne transporte pas cette donnée : elle est lue dans la fiche technique du
|
|
393
396
|
* générateur. Sans fiche technique, la ventouse est conservée comme approximation (choix
|
|
394
397
|
* Open3CL, la méthode ne prévoyant pas de valeur par défaut).
|
|
395
|
-
* @see
|
|
396
|
-
* @see
|
|
398
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
|
|
399
|
+
* @see Tribu Calcul_generateur.cs (ventilateur_combustion)
|
|
397
400
|
*/
|
|
398
401
|
const indexEF = de.ventilateurCombustion ?? de.presence_ventouse;
|
|
399
402
|
const E = E_tab[indexEF];
|
|
@@ -474,7 +477,7 @@ export function tv_generateur_combustion(
|
|
|
474
477
|
/**
|
|
475
478
|
* Mise à jour du type de générateur si besoin
|
|
476
479
|
* @param dpe {FullDpe}
|
|
477
|
-
* @param de {
|
|
480
|
+
* @param de {GenerateurChauffageDE|GenerateurEcsDE}
|
|
478
481
|
* @param type {'ch' | 'ecs'}
|
|
479
482
|
*/
|
|
480
483
|
export function updateGenerateurCombustion(dpe, de, type) {
|
|
@@ -515,7 +518,7 @@ export function valeurVeilleuse(valeur) {
|
|
|
515
518
|
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.4 / §14.1 (« Pveil : si veilleuse »)
|
|
516
519
|
*
|
|
517
520
|
* @param dpe {FullDpe}
|
|
518
|
-
* @param de {
|
|
521
|
+
* @param de {GenerateurChauffageDE|GenerateurEcsDE}
|
|
519
522
|
* @param type {'ch' | 'ecs'}
|
|
520
523
|
* @returns {1 | 0 | undefined} 1 si veilleuse, 0 si pas de veilleuse, undefined si non renseigné
|
|
521
524
|
*/
|
|
@@ -558,7 +561,7 @@ export function presenceVeilleuse(dpe, de, type) {
|
|
|
558
561
|
* Récupération d'informations complémentaires issues des fiches techniques pour les générateurs
|
|
559
562
|
*
|
|
560
563
|
* @param dpe {FullDpe}
|
|
561
|
-
* @param de {
|
|
564
|
+
* @param de {GenerateurChauffageDE|GenerateurEcsDE}
|
|
562
565
|
* @param type {'ch' | 'ecs'}
|
|
563
566
|
*/
|
|
564
567
|
function addInfosFromFichesTechniques(dpe, de, type) {
|
|
@@ -590,7 +593,7 @@ function addInfosFromFichesTechniques(dpe, de, type) {
|
|
|
590
593
|
* Vérifier que les informations du générateur ECS sont bien les mêmes que celles du générateur de chauffage
|
|
591
594
|
* Dans le cas d'une génération mixte, le type du générateur doit être le même
|
|
592
595
|
* @param dpe {FullDpe}
|
|
593
|
-
* @param de {
|
|
596
|
+
* @param de {GenerateurChauffageDE|GenerateurEcsDE}
|
|
594
597
|
* @param typeGenerateurKey {string}
|
|
595
598
|
* @returns {string}
|
|
596
599
|
*/
|
|
@@ -612,7 +615,7 @@ function checkEcsVsChauffageForMixteGeneration(dpe, de, typeGenerateurKey) {
|
|
|
612
615
|
}
|
|
613
616
|
|
|
614
617
|
/**
|
|
615
|
-
* @type {
|
|
618
|
+
* @type {InstallationChauffage[]}
|
|
616
619
|
*/
|
|
617
620
|
const installationsCh = dpe.logement.installation_chauffage_collection.installation_chauffage;
|
|
618
621
|
|
|
@@ -668,9 +671,9 @@ function checkEcsVsChauffageForMixteGeneration(dpe, de, typeGenerateurKey) {
|
|
|
668
671
|
* 3. même énergie (`enum_type_energie_id`), si un seul générateur de chauffage mixte correspond ;
|
|
669
672
|
* 4. générateur de chauffage mixte unique du DPE, si son énergie n'est pas incompatible.
|
|
670
673
|
*
|
|
671
|
-
* @param generateursChMixtes {
|
|
672
|
-
* @param de {
|
|
673
|
-
* @returns {
|
|
674
|
+
* @param generateursChMixtes {GenerateurChauffage[]} générateurs de chauffage d'usage 'chauffage + ecs'
|
|
675
|
+
* @param de {GenerateurEcsDE} données du générateur ECS
|
|
676
|
+
* @returns {GenerateurChauffage|null} null si aucun jumeau ne peut être identifié sans ambiguïté
|
|
674
677
|
*/
|
|
675
678
|
export function findGenerateurChMixteJumeau(generateursChMixtes, de) {
|
|
676
679
|
const sameValue = (a, b) =>
|
|
@@ -121,7 +121,7 @@ const ROW_DEFAUT = {
|
|
|
121
121
|
|
|
122
122
|
/**
|
|
123
123
|
* 13.2 - Récupération des caractéristiques forfaitaires d'un générateur à combustion.
|
|
124
|
-
* @see
|
|
124
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2
|
|
125
125
|
*/
|
|
126
126
|
describe('tv_generateur_combustion - caractéristiques du générateur', () => {
|
|
127
127
|
test('puissance nominale calculée à partir de GV et Tbase lorsqu’elle est absente', () => {
|
|
@@ -358,7 +358,7 @@ describe('tv_generateur_combustion - compatibilité bug_for_bug_compat', () => {
|
|
|
358
358
|
|
|
359
359
|
/**
|
|
360
360
|
* Système collectif par défaut : chaudière fioul standard datant de la construction du bâtiment.
|
|
361
|
-
* @see
|
|
361
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §17.2.1.1
|
|
362
362
|
*/
|
|
363
363
|
describe('système collectif par défaut : chaudière selon l’année de construction', () => {
|
|
364
364
|
test('CH 119 + ligne compatible : type et ligne de la période de construction retenus', () => {
|
|
@@ -668,7 +668,7 @@ describe('tv_generateur_combustion - génération mixte (checkEcsVsChauffageForM
|
|
|
668
668
|
/**
|
|
669
669
|
* Issue #210 : l'ECS mixte doit être appariée avec SON générateur de chauffage mixte (même appareil),
|
|
670
670
|
* et non avec le premier générateur de chauffage mixte du DPE.
|
|
671
|
-
* @see
|
|
671
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2 et §14
|
|
672
672
|
*/
|
|
673
673
|
describe('findGenerateurChMixteJumeau - appariement ECS / chauffage mixte (issue #210)', () => {
|
|
674
674
|
const ch = (donnees) => ({ donnee_entree: { enum_usage_generateur_id: '3', ...donnees } });
|
|
@@ -876,7 +876,7 @@ const dpeFiches = (...fiches) => ({
|
|
|
876
876
|
|
|
877
877
|
/**
|
|
878
878
|
* 13.2 - Orchestration des substitutions de générateurs et enrichissement fiches techniques.
|
|
879
|
-
* @see
|
|
879
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2
|
|
880
880
|
*/
|
|
881
881
|
describe('updateGenerateurCombustion - orchestration des substitutions', () => {
|
|
882
882
|
test('délègue aux trois routines de substitution avec les mêmes arguments', () => {
|
|
@@ -983,7 +983,7 @@ describe('updateGenerateurCombustion - orchestration des substitutions', () => {
|
|
|
983
983
|
/**
|
|
984
984
|
* Issue #35 : les coefficients (E, F) de la formule qp0 dépendent de la présence d'un ventilateur
|
|
985
985
|
* dans le circuit de combustion (fiche technique), la ventouse n'étant qu'un repli.
|
|
986
|
-
* @see
|
|
986
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
|
|
987
987
|
*/
|
|
988
988
|
describe('tv_generateur_combustion - coefficients (E, F) selon le ventilateur de combustion (#35)', () => {
|
|
989
989
|
const ROW_EF = { ...ROW_DEFAUT, rpn: 'E*40', qp0_perc: 'Pn*(E+F*log10(Pn))/100' };
|
|
@@ -1032,7 +1032,7 @@ describe('tv_generateur_combustion - coefficients (E, F) selon le ventilateur de
|
|
|
1032
1032
|
* Issue #39 : présence d'une veilleuse lue dans la sous-fiche technique du générateur.
|
|
1033
1033
|
* Tribu : entrée `Is_veilleuse` (DPE.DataClasses/generateur.cs), Pveil1 = 0 si absente
|
|
1034
1034
|
* (DPE.Core/Calcul_generateur.cs).
|
|
1035
|
-
* @see
|
|
1035
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.4 / §14.1
|
|
1036
1036
|
*/
|
|
1037
1037
|
describe('presenceVeilleuse - fiche technique « Présence d’une veilleuse »', () => {
|
|
1038
1038
|
const ficheGen = (desc, veilleuse) => [
|
|
@@ -1151,7 +1151,7 @@ describe('presenceVeilleuse - fiche technique « Présence d’une veilleuse »'
|
|
|
1151
1151
|
/**
|
|
1152
1152
|
* Issue #124 : générateur collectif virtualisé, puissance saisie collective (Pn) ou individualisée
|
|
1153
1153
|
* (Pe = a × Pn) selon les logiciels.
|
|
1154
|
-
* @see
|
|
1154
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2 et §17.2.1
|
|
1155
1155
|
*/
|
|
1156
1156
|
describe('tv_generateur_combustion - convention de puissance d’un générateur virtualisé (#124)', () => {
|
|
1157
1157
|
const ROW_PN = {
|
|
@@ -1418,7 +1418,7 @@ describe('caracteristiquesGenerateurCombustion - selon la méthode de saisie', (
|
|
|
1418
1418
|
/**
|
|
1419
1419
|
* Plafond de Pn à 400 kW dans Qp0 = Pn × (E + F × log Pn) / 100 des chaudières gaz après 2015
|
|
1420
1420
|
* (moteur de référence Tribu : Calcul_generateur.cs, Rpn_chaudieregaz, Math.Min(400.0, Pn)).
|
|
1421
|
-
* @see
|
|
1421
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2
|
|
1422
1422
|
*/
|
|
1423
1423
|
describe('puissanceFormuleQp0 - plafond de Pn à 400 kW pour les chaudières gaz', () => {
|
|
1424
1424
|
const ROW_GAZ = {
|
|
@@ -1486,7 +1486,7 @@ describe('puissanceFormuleQp0 - plafond de Pn à 400 kW pour les chaudières gaz
|
|
|
1486
1486
|
|
|
1487
1487
|
/**
|
|
1488
1488
|
* Estimation de la puissance nominale d'un générateur à combustion (pn absente).
|
|
1489
|
-
* @see
|
|
1489
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2.4
|
|
1490
1490
|
*/
|
|
1491
1491
|
describe('pnEstimee - puissance nominale estimée (issue #264)', () => {
|
|
1492
1492
|
// 1,2 × 200 × (19 − (−9)) / 0,95³ -- valeur de référence de régression
|
|
@@ -1518,7 +1518,7 @@ describe('pnEstimee - puissance nominale estimée (issue #264)', () => {
|
|
|
1518
1518
|
|
|
1519
1519
|
/**
|
|
1520
1520
|
* Pn estimée par la puissance de dimensionnement (issue #271).
|
|
1521
|
-
* @see
|
|
1521
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.2.2.4
|
|
1522
1522
|
*/
|
|
1523
1523
|
describe('pnEstimeeGenerateur - Pdim = max(Pch ; Pecs) et table Pdim → Pn (issue #271)', () => {
|
|
1524
1524
|
const dpeAvecEcsMixte = (generateursEcs) => ({
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
/** @import { FullDpe } from './features/dpe/domain/models/dpe.model.js' */
|
|
2
|
+
/** @import { GenerateurChauffageDE } from './features/dpe/domain/models/installation-chauffage.model.js' */
|
|
3
|
+
/** @import { GenerateurEcsDE } from './features/dpe/domain/models/installation-ecs.model.js' */
|
|
1
4
|
import getFicheTechnique from './ficheTechnique.js';
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* Pour les générateurs "poêles à bois bouilleur", les calculs sont faits comme pour les chaudières bois
|
|
5
8
|
* @param dpe {FullDpe}
|
|
6
|
-
* @param de {
|
|
9
|
+
* @param de {GenerateurChauffageDE|GenerateurEcsDE}
|
|
7
10
|
* @param type {'ch' | 'ecs'}
|
|
8
11
|
*/
|
|
9
12
|
export function updateGenerateurBouilleurs(dpe, de, type) {
|
|
@@ -121,7 +124,7 @@ export function updateGenerateurBouilleurs(dpe, de, type) {
|
|
|
121
124
|
* - Pour un poêle à bois bouilleur bûche installé avant 1948, on prendra la chaudière bois bûche avant 1978
|
|
122
125
|
* @param dpe {FullDpe}
|
|
123
126
|
* @param ids
|
|
124
|
-
* @param de {
|
|
127
|
+
* @param de {GenerateurChauffageDE|GenerateurEcsDE}
|
|
125
128
|
* @param type {'ch' | 'ecs'}
|
|
126
129
|
*/
|
|
127
130
|
function updateGenerateurBouilleur(dpe, ids, de, type) {
|
|
@@ -18,7 +18,7 @@ beforeEach(() => {
|
|
|
18
18
|
/**
|
|
19
19
|
* 13.1 - Les poêles à bois bouilleur sont assimilés à des chaudières bois de la
|
|
20
20
|
* période correspondante.
|
|
21
|
-
* @see
|
|
21
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - §13.1
|
|
22
22
|
*/
|
|
23
23
|
describe('updateGenerateurBouilleurs - substitution par une chaudière bois équivalente', () => {
|
|
24
24
|
test('type non concerné : aucune substitution', () => {
|