@open3cl/engine 1.0.0

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.
Files changed (85) hide show
  1. package/10_besoin_fr.js +76 -0
  2. package/10_clim.js +45 -0
  3. package/11_besoin_ecs.js +25 -0
  4. package/11_ecs.js +95 -0
  5. package/11_nadeq.js +87 -0
  6. package/11_nadeq.spec.js +55 -0
  7. package/12.4_pac.js +54 -0
  8. package/13.2_generateur_combustion.js +295 -0
  9. package/13.2_generateur_combustion_bouilleur.js +173 -0
  10. package/13.2_generateur_combustion_ch.js +195 -0
  11. package/13.2_generateur_combustion_chaudiere.js +151 -0
  12. package/13.2_generateur_pac.js +36 -0
  13. package/13_rendement_distribution_ecs.js +12 -0
  14. package/14_generateur_ecs.js +388 -0
  15. package/15_conso_aux.js +257 -0
  16. package/16.2_production_enr.js +328 -0
  17. package/16.2_production_enr.spec.js +251 -0
  18. package/16_conso_eclairage.js +37 -0
  19. package/2021_04_13_confort_ete.js +61 -0
  20. package/2021_04_13_qualite_isolation.js +174 -0
  21. package/3.1_b.js +141 -0
  22. package/3.2.1_mur.js +331 -0
  23. package/3.2.1_mur.spec.js +46 -0
  24. package/3.2.2_plancher_bas.js +259 -0
  25. package/3.2.2_plancher_bas.spec.js +88 -0
  26. package/3.2.3_plancher_haut.js +158 -0
  27. package/3.3.1.4_porte.js +32 -0
  28. package/3.3_baie_vitree.js +308 -0
  29. package/3.3_baie_vitree.spec.js +333 -0
  30. package/3.4_pont_thermique.js +463 -0
  31. package/3_deperdition.js +258 -0
  32. package/4_ventilation.js +197 -0
  33. package/5_conso_ventilation.js +127 -0
  34. package/6.1_apport_gratuit.js +61 -0
  35. package/6.1_apport_gratuit.spec.js +181 -0
  36. package/6.2_surface_sud_equivalente.js +109 -0
  37. package/7_inertie.js +178 -0
  38. package/7_inertie.spec.js +263 -0
  39. package/8_intermittence.js +5 -0
  40. package/9_besoin_ch.js +198 -0
  41. package/9_chauffage.js +291 -0
  42. package/9_chauffage.spec.js +101 -0
  43. package/9_conso_ch.js +95 -0
  44. package/9_conso_ch.spec.js +255 -0
  45. package/9_emetteur_ch.js +122 -0
  46. package/9_generateur_ch.js +230 -0
  47. package/9_generateur_ch.spec.js +87 -0
  48. package/README.md +43 -0
  49. package/apport_et_besoin.js +55 -0
  50. package/conso.js +529 -0
  51. package/conso.spec.js +90 -0
  52. package/core/assets/domain/add-additionnal-ue-values-tables.js +57 -0
  53. package/core/assets/domain/synchronize-assets.js +29 -0
  54. package/core/assets/domain/synchronize-assets.spec.js +37 -0
  55. package/core/assets/domain/synchronize-c1-tables.js +61 -0
  56. package/core/assets/domain/synchronize-c1-tables.spec.js +35 -0
  57. package/core/assets/domain/synchronize-dpe-ges-limit-values-tables.js +73 -0
  58. package/core/assets/domain/synchronize-dpe-ges-limit-values-tables.spec.js +72 -0
  59. package/core/assets/domain/synchronize-enum-tables.js +77 -0
  60. package/core/assets/domain/synchronize-enum-tables.spec.js +31 -0
  61. package/core/assets/domain/synchronize-solicitations-tables.js +72 -0
  62. package/core/assets/domain/synchronize-solicitations-tables.spec.js +47 -0
  63. package/core/assets/domain/synchronize-valeur-tables.js +146 -0
  64. package/core/assets/domain/synchronize-valeur-tables.spec.js +54 -0
  65. package/core/conf/infrastructure/application.config.js +33 -0
  66. package/core/file/infrastructure/adapter/file.store.js +75 -0
  67. package/core/file/infrastructure/adapter/file.store.spec.js +30 -0
  68. package/core/tv/infrastructure/assets/additional-ue-values.js +69 -0
  69. package/core/tv/infrastructure/tvs.store.js +40 -0
  70. package/core/tv/infrastructure/tvs.store.spec.js +34 -0
  71. package/core/util/infrastructure/object-util.js +23 -0
  72. package/core/util/infrastructure/object-util.spec.js +25 -0
  73. package/engine.js +503 -0
  74. package/enums.js +1155 -0
  75. package/ficheTechnique.js +86 -0
  76. package/ficheTechnique.spec.js +181 -0
  77. package/index.js +4 -0
  78. package/package.json +87 -0
  79. package/tv/18.2_sollicitations_ext.ods +0 -0
  80. package/tv/18.5_c1.ods +0 -0
  81. package/tv/dpe_ges_limit_values.ods +0 -0
  82. package/tv.js +80811 -0
  83. package/tvs.d.ts +7 -0
  84. package/utils.js +500 -0
  85. package/utils.spec.js +36 -0
package/9_chauffage.js ADDED
@@ -0,0 +1,291 @@
1
+ import { requestInput, Tbase, tv, tvColumnIDs } from './utils.js';
2
+ import { calc_emetteur_ch } from './9_emetteur_ch.js';
3
+ import {
4
+ calc_generateur_ch,
5
+ checkForGeneratorType,
6
+ hasConsoForAuxDistribution
7
+ } from './9_generateur_ch.js';
8
+ import { tv_generateur_combustion } from './13.2_generateur_combustion.js';
9
+ import { tv_temp_fonc_30_100 } from './13.2_generateur_combustion_ch.js';
10
+ import enums from './enums.js';
11
+
12
+ export default function calc_chauffage(
13
+ dpe,
14
+ ch,
15
+ ca_id,
16
+ zc_id,
17
+ inertie_id,
18
+ map_id,
19
+ bch,
20
+ bch_dep,
21
+ GV,
22
+ Sh,
23
+ hsp,
24
+ ac,
25
+ ilpa
26
+ ) {
27
+ const de = ch.donnee_entree;
28
+ const di = {};
29
+ const du = {};
30
+
31
+ const ca = enums.classe_altitude[ca_id];
32
+ const zc = enums.zone_climatique[zc_id];
33
+ const tbase = Tbase[ca][zc.slice(0, 2)];
34
+
35
+ di.besoin_ch = bch;
36
+ di.besoin_ch_depensier = bch_dep;
37
+
38
+ const em_ch = ch.emetteur_chauffage_collection.emetteur_chauffage;
39
+ em_ch.forEach((em_ch) => {
40
+ calc_emetteur_ch(em_ch, de, map_id, inertie_id);
41
+ });
42
+
43
+ if (de.surface_chauffee !== Sh) {
44
+ bch *= de.surface_chauffee / Sh;
45
+ }
46
+
47
+ const Fch = tv_ch_facteur_couverture_solaire(de, zc_id);
48
+ const cfg_id = requestInput(de, du, 'cfg_installation_ch');
49
+ const gen_ch = ch.generateur_chauffage_collection.generateur_chauffage;
50
+
51
+ gen_ch.forEach((gen) => {
52
+ const genChDe = gen.donnee_entree;
53
+ const genChDu = gen.donnee_utilisateur || {};
54
+ const genChDi = gen.donnee_intermediaire || {};
55
+
56
+ genChDe.ratio_virtualisation = de.ratio_virtualisation || 1;
57
+ genChDe.surface_chauffee = de.surface_chauffee || Sh;
58
+ genChDe.nombre_niveau_installation_ch = de.nombre_niveau_installation_ch || 1;
59
+ genChDe.fch = Fch || 0.5;
60
+
61
+ // Récupération du type de générateur
62
+ checkForGeneratorType(dpe, genChDe, genChDi, genChDu);
63
+
64
+ if (genChDu.isCombustionGenerator) {
65
+ const methodeSaisie = parseInt(genChDe.enum_methode_saisie_carac_sys_id);
66
+ tv_generateur_combustion(dpe, genChDi, genChDe, 'ch', GV, tbase, methodeSaisie);
67
+
68
+ const type_gen_ch_list = tvColumnIDs('temp_fonc_30', 'type_generateur_ch');
69
+ if (type_gen_ch_list.includes(genChDe.enum_type_generateur_ch_id)) {
70
+ /**
71
+ * Si la méthode de saisie n'est pas "Valeur forfaitaire" mais "caractéristiques saisies"
72
+ * Documentation 3CL : "Pour les installations récentes ou recommandées, les caractéristiques réelles des chaudières présentées sur les bases
73
+ * de données professionnelles peuvent être utilisées."
74
+ *
75
+ * 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
76
+ */
77
+ if (methodeSaisie !== 5 || !genChDi.temp_fonc_30 || !genChDi.temp_fonc_100) {
78
+ tv_temp_fonc_30_100(genChDi, genChDe, genChDu, em_ch, ac);
79
+ }
80
+ }
81
+ }
82
+
83
+ gen.donnee_intermediaire = genChDi;
84
+ gen.donnee_utilisateur = genChDu;
85
+ gen.donnee_entree = genChDe;
86
+ });
87
+
88
+ /**
89
+ * 13.2.1.3 Cascade de deux générateurs à combustion
90
+ * Une puissance relative pour chaque générateur est calculée et appliquée à la conso globale de chauffage
91
+ * Seuls les générateurs en cascade sont concernés
92
+ *
93
+ * 9.1.4.3 Les pompes à chaleur hybrides
94
+ * Cas particulier des PAC hybrides avec répartition forfaitaire du besoin
95
+ * @type {number|number}
96
+ */
97
+ const Pnominal = gen_ch.reduce((acc, gen) => acc + (gen.donnee_intermediaire.pn || 0), 0);
98
+ du.Pnominal = Pnominal;
99
+
100
+ const nbCascadeAndCombustion = gen_ch.filter(
101
+ (value) =>
102
+ value.donnee_utilisateur.isCombustionGenerator &&
103
+ Number.parseInt(de.enum_cfg_installation_ch_id) === 1
104
+ ).length;
105
+
106
+ // Nombre de générateurs avec une consommation des auxiliaires de distribution
107
+ const nbGenWithAuxConsoDistribution = gen_ch.reduce((acc, gen) => {
108
+ if (hasConsoForAuxDistribution(gen.donnee_entree.enum_type_generateur_ch_id)) {
109
+ acc++;
110
+ }
111
+ return acc;
112
+ }, 0);
113
+
114
+ gen_ch.forEach((gen, _pos) => {
115
+ // Nombre de générateurs en cascade pour un même émetteur si l'installation est une installation simple
116
+ const nbEmetteur = em_ch.filter(
117
+ (em) =>
118
+ em.donnee_entree.enum_lien_generateur_emetteur_id ===
119
+ gen.donnee_entree.enum_lien_generateur_emetteur_id
120
+ ).length;
121
+ const nbCascadeForSameEmetteur =
122
+ Number.parseInt(de.enum_cfg_installation_ch_id) === 1 && nbEmetteur === 1
123
+ ? gen_ch.filter(
124
+ (gen_ch) =>
125
+ gen_ch.donnee_entree.enum_lien_generateur_emetteur_id ===
126
+ gen.donnee_entree.enum_lien_generateur_emetteur_id
127
+ ).length
128
+ : 0;
129
+
130
+ const prorataGenerateur = getProrataGenerateur(
131
+ gen,
132
+ nbCascadeAndCombustion,
133
+ nbCascadeForSameEmetteur,
134
+ Pnominal,
135
+ zc
136
+ );
137
+ (gen.donnee_utilisateur = gen.donnee_utilisateur || {}).nbGenerateurCascade = gen_ch.length;
138
+
139
+ calc_generateur_ch(
140
+ dpe,
141
+ gen,
142
+ _pos,
143
+ em_ch,
144
+ cfg_id,
145
+ bch * prorataGenerateur,
146
+ bch_dep * prorataGenerateur,
147
+ GV,
148
+ Sh,
149
+ hsp,
150
+ ca_id,
151
+ zc_id,
152
+ ilpa
153
+ );
154
+
155
+ // Si plusieurs générateurs de chauffage, la consommation des auxiliaires est répartie sur chacun d'eux
156
+ if (
157
+ gen.donnee_intermediaire.conso_auxiliaire_distribution_ch &&
158
+ nbGenWithAuxConsoDistribution > 0
159
+ ) {
160
+ gen.donnee_intermediaire.conso_auxiliaire_distribution_ch /= nbGenWithAuxConsoDistribution;
161
+ }
162
+ });
163
+
164
+ di.conso_ch = gen_ch.reduce((acc, gen_ch) => acc + gen_ch.donnee_intermediaire.conso_ch, 0);
165
+ di.conso_ch_depensier = gen_ch.reduce(
166
+ (acc, gen_ch) => acc + gen_ch.donnee_intermediaire.conso_ch_depensier,
167
+ 0
168
+ );
169
+
170
+ ch.donnee_intermediaire = di;
171
+ ch.donnee_utilisateur = du;
172
+ }
173
+
174
+ /**
175
+ * 13.2.1.3 Cascade de deux générateurs à combustion
176
+ * Une puissance relative pour chaque générateur est calculée et appliquée à la conso globale de chauffage
177
+ * Seuls les générateurs en cascade sont concernés
178
+ *
179
+ * 9.1.4.3 Les pompes à chaleur hybrides
180
+ * Cas particulier des PAC hybrides avec répartition forfaitaire du besoin
181
+ * @type {number|number}
182
+ */
183
+ function getProrataGenerateur(genCh, nbCascadeAndCombustion, nbGenerateurCascade, Pnominal, zc) {
184
+ // IDs des pompes à chaleur hybrides
185
+ if (
186
+ genCh.donnee_entree.enum_type_generateur_ch_id >= 145 &&
187
+ genCh.donnee_entree.enum_type_generateur_ch_id <= 170
188
+ ) {
189
+ const zone = zc.slice(0, 2);
190
+ const hybrideProrata = {
191
+ h1: {
192
+ pac: 0.8,
193
+ chaudiere: 0.2
194
+ },
195
+ h2: {
196
+ pac: 0.83,
197
+ chaudiere: 0.17
198
+ },
199
+ h3: {
200
+ pac: 0.88,
201
+ chaudiere: 0.12
202
+ }
203
+ };
204
+
205
+ // Partie PAC du générateur
206
+ if (genCh.donnee_intermediaire.scop || genCh.donnee_intermediaire.cop) {
207
+ return hybrideProrata[zone]['pac'];
208
+ } else {
209
+ return hybrideProrata[zone]['chaudiere'];
210
+ }
211
+ }
212
+
213
+ return nbCascadeAndCombustion > 1
214
+ ? genCh.donnee_intermediaire.pn / Pnominal
215
+ : 1 / (nbGenerateurCascade || 1);
216
+ }
217
+
218
+ /**
219
+ * Retourne le facteur de couverture solaire pour les maisons avec chauffage solaire
220
+ * @param de {Donnee_entree}
221
+ * @param zc_id {int}
222
+ * @returns {number|*|null}
223
+ */
224
+ function tv_ch_facteur_couverture_solaire(de, zc_id) {
225
+ /**
226
+ * 18.4 Facteur de couverture solaire
227
+ * Les facteurs de couverture solaire peuvent être saisi directement quand ils sont connus et peuvent être justifiés.
228
+ */
229
+ if (de.fch_saisi) {
230
+ return de.fch_saisi;
231
+ }
232
+
233
+ const matcher = {
234
+ enum_zone_climatique_id: zc_id
235
+ };
236
+
237
+ const row = tv('facteur_couverture_solaire', matcher);
238
+ if (row) {
239
+ return Number(row.facteur_couverture_solaire);
240
+ } else {
241
+ console.error('!! pas de valeur forfaitaire trouvée pour facteur_couverture_solaire !!');
242
+ return null;
243
+ }
244
+ }
245
+
246
+ /**
247
+ * 13.2.1.2 Présence d’un ou plusieurs générateurs à combustion indépendants
248
+ * Calcul du taux de charge cdimref et cdimrefDep pour chacun des générateurs
249
+ *
250
+ * @param installationChauffage {InstallationChauffageItem[]}
251
+ * @param GV {number} déperdition de l'enveloppe
252
+ * @param zcId {string} id de la zone climatique du bien
253
+ * @param caId {string} id de la classe d'altitude du bien
254
+ */
255
+ export function tauxChargeForGenerator(installationChauffage, GV, caId, zcId) {
256
+ // Récupération des installations de chauffage avec générateur à combustion
257
+ const installChauffageWithCombustion = [];
258
+ installationChauffage.forEach((ch) => {
259
+ const gen_ch = ch.generateur_chauffage_collection.generateur_chauffage;
260
+
261
+ const genCombustion = gen_ch.reduce((acc, gen) => {
262
+ if (gen.donnee_utilisateur.isCombustionGenerator) {
263
+ acc.push(gen);
264
+ }
265
+
266
+ return acc;
267
+ }, []);
268
+
269
+ if (genCombustion.length) {
270
+ ch.donnee_utilisateur.genCombustion = genCombustion;
271
+ installChauffageWithCombustion.push(ch);
272
+ }
273
+ });
274
+
275
+ const ca = enums.classe_altitude[caId];
276
+ const zc = enums.zone_climatique[zcId];
277
+ const tbase = Tbase[ca][zc.slice(0, 2)];
278
+
279
+ // Pour N générateurs à combustion, puissance totale de tous les générateurs
280
+ const Pn = installChauffageWithCombustion.reduce(
281
+ (acc, gen) => acc + gen.donnee_utilisateur.Pnominal,
282
+ 0
283
+ );
284
+
285
+ installChauffageWithCombustion.forEach((installCh) => {
286
+ (installCh.donnee_utilisateur.genCombustion || []).forEach((gen) => {
287
+ gen.donnee_utilisateur.cdimref = Pn / (GV * (19 - tbase));
288
+ gen.donnee_utilisateur.cdimrefDep = Pn / (GV * (21 - tbase));
289
+ });
290
+ });
291
+ }
@@ -0,0 +1,101 @@
1
+ import calc_chauffage from './9_chauffage.js';
2
+
3
+ describe('Recherche de bugs dans le calcul de la consommation', () => {
4
+ test('calcul de la consommation de chauffage pour 2475E2510509B', () => {
5
+ const Sh = 22.76; // Surface habitable
6
+ const zc_id = 1; // Zone climatique
7
+ const ca_id = 1; // Classe d'altitude
8
+ const inertie_id = 4; // Inertie du batiment
9
+ const map_id = 2; // Méthode d'application du DPE (enum_methode_application_dpe_log_id)
10
+ const bch = 7998.446638037776; // Besoin en chauffage
11
+ const bch_dep = 9714.925476692655; // Besoin en chauffage dépensier
12
+ const GV = 150.18558182166174; // Déperdition de l'enveloppe
13
+ const hsp = 2.5700000000000003; // Hauteur sous plafond
14
+ const ac = 1; // Période de construction
15
+
16
+ const ch = {
17
+ donnee_entree: {
18
+ description:
19
+ 'Convecteur électrique NFC, NF** et NF*** avec programmateur pièce par pièce (système individuel)',
20
+ reference: '2024_07_11_09_30_44_722898200737262',
21
+ surface_chauffee: 22.76,
22
+ rdim: 1,
23
+ nombre_niveau_installation_ch: 1,
24
+ enum_cfg_installation_ch_id: '1',
25
+ enum_type_installation_id: '1',
26
+ enum_methode_calcul_conso_id: '1'
27
+ },
28
+ emetteur_chauffage_collection: {
29
+ emetteur_chauffage: [
30
+ {
31
+ donnee_entree: {
32
+ description: '',
33
+ reference: 'Emetteur:2024_07_11_09_30_44_722898200737262#1',
34
+ surface_chauffee: 22.76,
35
+ tv_rendement_emission_id: 1,
36
+ tv_rendement_distribution_ch_id: 1,
37
+ tv_rendement_regulation_id: 1,
38
+ enum_type_emission_distribution_id: '1',
39
+ tv_intermittence_id: 138,
40
+ reseau_distribution_isole: 0,
41
+ enum_equipement_intermittence_id: '4',
42
+ enum_type_regulation_id: '2',
43
+ enum_periode_installation_emetteur_id: '1',
44
+ enum_type_chauffage_id: '1',
45
+ enum_temp_distribution_ch_id: '1',
46
+ enum_lien_generateur_emetteur_id: '1'
47
+ }
48
+ }
49
+ ]
50
+ },
51
+ generateur_chauffage_collection: {
52
+ generateur_chauffage: [
53
+ {
54
+ donnee_entree: {
55
+ description: 'Electrique - Convecteur électrique NFC, NF** et NF***',
56
+ reference: 'Generateur:2024_07_11_09_30_44_722898200737262#1',
57
+ reference_generateur_mixte: '',
58
+ ref_produit_generateur_ch: 'Sans Objet',
59
+ enum_type_generateur_ch_id: '98',
60
+ enum_usage_generateur_id: '1',
61
+ enum_type_energie_id: '1',
62
+ position_volume_chauffe: 1,
63
+ tv_rendement_generation_id: 29,
64
+ identifiant_reseau_chaleur: '',
65
+ enum_methode_saisie_carac_sys_id: '1',
66
+ enum_lien_generateur_emetteur_id: '1'
67
+ }
68
+ }
69
+ ]
70
+ }
71
+ };
72
+
73
+ calc_chauffage(ch, ca_id, zc_id, inertie_id, map_id, bch, bch_dep, GV, Sh, hsp, ac);
74
+
75
+ expect(ch.donnee_intermediaire).toStrictEqual({
76
+ besoin_ch: 7998.446638037776,
77
+ besoin_ch_depensier: 9714.925476692655,
78
+ conso_ch: 6322.706769289927,
79
+ conso_ch_depensier: 7679.569278179351
80
+ });
81
+ expect(
82
+ ch.emetteur_chauffage_collection.emetteur_chauffage[0].donnee_intermediaire
83
+ ).toStrictEqual({
84
+ i0: 0.86,
85
+ rendement_distribution: 1,
86
+ rendement_emission: 0.95,
87
+ rendement_regulation: 0.99
88
+ });
89
+ expect(
90
+ ch.generateur_chauffage_collection.generateur_chauffage[0].donnee_intermediaire
91
+ ).toStrictEqual({
92
+ conso_auxiliaire_generation_ch: 0,
93
+ conso_auxiliaire_generation_ch_depensier: 0,
94
+ conso_ch: 6322.706769289927,
95
+ conso_ch_depensier: 7679.569278179351,
96
+ rendement_generation: 1,
97
+ rg: 1,
98
+ rg_dep: 1
99
+ });
100
+ });
101
+ });
package/9_conso_ch.js ADDED
@@ -0,0 +1,95 @@
1
+ import { requestInputID } from './utils.js';
2
+ import { rendement_emission } from './9_emetteur_ch.js';
3
+ import { calc_intermittence } from './8_intermittence.js';
4
+
5
+ function coef_ch(Fch) {
6
+ return {
7
+ 'installation de chauffage simple': {
8
+ 0: 1,
9
+ 1: 1
10
+ },
11
+ 'installation de chauffage avec chauffage solaire': {
12
+ 0: 1 - Fch
13
+ },
14
+ 'installation de chauffage avec insert ou poêle bois en appoint': {
15
+ 0: 0.75,
16
+ 1: 0.25
17
+ },
18
+ // todo: 2 sdb
19
+ 'installation de chauffage par insert, poêle bois (ou biomasse) avec un chauffage électrique dans la salle de bain':
20
+ {
21
+ 0: 0.9,
22
+ 1: 0.1
23
+ },
24
+ 'installation de chauffage avec en appoint un insert ou poêle bois et un chauffage électrique dans la salle de bain (différent du chauffage principal)':
25
+ {
26
+ 0: 0.75 * 0.9,
27
+ 1: 0.25 * 0.9,
28
+ 2: 0.1
29
+ },
30
+ 'installation de chauffage avec une chaudière ou une pac en relève d’une chaudière bois': {
31
+ 0: 0.75,
32
+ 1: 0.25
33
+ },
34
+ 'installation de chauffage avec chauffage solaire et insert ou poêle bois en appoint': {
35
+ 0: 0.75 * (1 - Fch),
36
+ 1: 0.25 * (1 - Fch)
37
+ },
38
+ 'installation de chauffage avec chaudière en relève de pac': {
39
+ 0: 0.8,
40
+ 1: 0.2
41
+ },
42
+ 'installation de chauffage avec chaudière en relève de pac avec insert ou poêle bois en appoint':
43
+ {
44
+ 0: 0.8 * 0.75,
45
+ 1: 0.2 * 0.75,
46
+ 2: 0.25
47
+ },
48
+ 'installation de chauffage collectif avec base + appoint': {
49
+ 0: 0.75 * (1 - Fch),
50
+ 1: 0.25 * (1 - Fch)
51
+ },
52
+ 'convecteurs bi-jonction': {
53
+ 0: 0.6,
54
+ 1: 0.4
55
+ }
56
+ };
57
+ }
58
+
59
+ export function conso_ch(di, de, du, _pos, cfg_ch, em_list, GV, Sh, hsp, bch, bch_dep) {
60
+ const gen_lge_id = requestInputID(de, du, 'lien_generateur_emetteur');
61
+ const coef = coef_ch(de.fch || 0.5)[cfg_ch][_pos] || 1;
62
+ let em_filt;
63
+
64
+ if (em_list.length === 1) {
65
+ em_filt = em_list;
66
+ } else {
67
+ em_filt = em_list.filter(
68
+ (em) => em.donnee_entree.enum_lien_generateur_emetteur_id === gen_lge_id
69
+ );
70
+ }
71
+
72
+ const hasMultipleEmetteur = em_filt.length > 1;
73
+
74
+ const emetteur_eq = em_filt.reduce((acc, em) => {
75
+ const int = calc_intermittence(GV, Sh, hsp, em.donnee_intermediaire.i0);
76
+ const r_em = rendement_emission(em);
77
+
78
+ /**
79
+ * 9.1.3 Installation avec plusieurs émissions pour un même générateur
80
+ * La part de la consommation traitée par chaque émetteur est proratisé par le ratio des surfaces habitables.
81
+ * @type {number|number}
82
+ */
83
+ const ratio_s = hasMultipleEmetteur
84
+ ? em.donnee_entree.surface_chauffee / de.surface_chauffee
85
+ : 1;
86
+
87
+ const Ich = 1 / r_em;
88
+ return acc + ratio_s * int * Ich;
89
+ }, 0);
90
+
91
+ const Ich = emetteur_eq / di.rg;
92
+ const Ich_dep = emetteur_eq / di.rg_dep;
93
+ di.conso_ch = coef * Ich * bch;
94
+ di.conso_ch_depensier = coef * Ich_dep * bch_dep;
95
+ }