@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
@@ -0,0 +1,295 @@
1
+ import { bug_for_bug_compat, convertExpression, tv, tvColumnLines } from './utils.js';
2
+ import enums from './enums.js';
3
+ import { updateGenerateurBouilleurs } from './13.2_generateur_combustion_bouilleur.js';
4
+ import { updateGenerateurChaudieres } from './13.2_generateur_combustion_chaudiere.js';
5
+ import { updateGenerateurPacs } from './13.2_generateur_pac.js';
6
+ import getFicheTechnique from './ficheTechnique.js';
7
+
8
+ function criterePn(Pn, matcher) {
9
+ let critere_list = tvColumnLines('generateur_combustion', 'critere_pn', matcher);
10
+ critere_list = critere_list.filter((critere) => critere);
11
+ let ret;
12
+ if (critere_list.length === 0) {
13
+ ret = null;
14
+ } else {
15
+ // change ≤ to <= in all critere_list
16
+ critere_list = critere_list.map((c) => c.replace('≤', '<='));
17
+ // find critere in critere_list that is true when executed
18
+ for (const critere of critere_list) {
19
+ if (eval(`let Pn=${Pn} ;${convertExpression(critere)}`)) {
20
+ ret = critere.replace('<=', '≤');
21
+ break;
22
+ }
23
+ }
24
+ if (!ret) console.warn('!! pas de critere trouvé pour pn !!');
25
+ }
26
+ return ret;
27
+ }
28
+
29
+ const E_tab = {
30
+ 0: 2.5,
31
+ 1: 1.75
32
+ };
33
+
34
+ const F_tab = {
35
+ 0: -0.8,
36
+ 1: -0.55
37
+ };
38
+
39
+ function excel_to_js_exec(box, pn, E, F) {
40
+ const formula = box
41
+ .replace(/ /g, '')
42
+ .replace(/,/g, '.')
43
+ .replace(/\*logPn/g, '*Math.log10(Pn)')
44
+ .replace(/\+logPn/g, '+Math.log10(Pn)')
45
+ .replace(/logPn/g, '*Math.log10(Pn)')
46
+ .replace(/%/g, '/100')
47
+ .replace(/\^/g, '**');
48
+ const js = `let Pn=${pn / 1000}, E=${E}, F=${F}; (${formula})`;
49
+ /* console.warn(js) */
50
+ const result = eval(js);
51
+ /* console.warn(result) */
52
+ return result;
53
+ }
54
+
55
+ /**
56
+ * Si la méthode de saisie n'est pas "Valeur forfaitaire" mais "caractéristiques saisies"
57
+ * Documentation 3CL : "Pour les installations récentes ou recommandées, les caractéristiques réelles des chaudières présentées sur les bases
58
+ * de données professionnelles peuvent être utilisées."
59
+ *
60
+ * 2 - caractéristiques saisies à partir de la plaque signalétique ou d'une documentation technique du système à combustion : pn, autres données forfaitaires
61
+ * 3 - caractéristiques saisies à partir de la plaque signalétique ou d'une documentation technique du système à combustion : pn, rpn,rpint, autres données forfaitaires
62
+ * 4 - caractéristiques saisies à partir de la plaque signalétique ou d'une documentation technique du système à combustion : pn, rpn,rpint,qp0, autres données forfaitaires
63
+ * 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
64
+ *
65
+ * @param dpe {FullDpe}
66
+ * @param di {Donnee_intermediaire} données du générateur
67
+ * @param de {Donnee_entree} données du générateur
68
+ * @param type {'ecs'|'ch'}
69
+ * @param GV {number} déperdition de l'enveloppe
70
+ * @param tbase {number} température de fonctionnement du générateur
71
+ * @param methodeSaisie {number} méthode de saisie des caractéristiques du générateur
72
+ */
73
+ export function tv_generateur_combustion(dpe, di, de, type, GV, tbase, methodeSaisie) {
74
+ const typeGenerateurKey = `enum_type_generateur_${type}_id`;
75
+ let enumTypeGenerateurId = de[typeGenerateurKey];
76
+ let row;
77
+
78
+ /**
79
+ * Certains DPE configurent mal les données du générateur ECS lorsque c'est un générateur mixte Chauffage + ECS
80
+ * Confrontation du type de générateur ECS et CH et prise en compte des données du générateur de chauffage
81
+ *
82
+ * enum_usage_generateur_id = 3 - 'chauffage + ecs'
83
+ */
84
+ if (bug_for_bug_compat && type === 'ecs' && de.enum_usage_generateur_id === '3') {
85
+ enumTypeGenerateurId = checkEcsVsChauffageForMixteGeneration(dpe, de, typeGenerateurKey);
86
+ }
87
+
88
+ /**
89
+ * Si le type de générateur est
90
+ * 84 - ECS - système collectif par défaut en abscence d'information : chaudière fioul pénalisante
91
+ * 119 - CH - système collectif par défaut en abscence d'information : chaudière fioul pénalisante
92
+ * On garde l'information à partir de tv_generateur_combustion_id.
93
+ */
94
+ if (
95
+ bug_for_bug_compat &&
96
+ ((type === 'ecs' && enumTypeGenerateurId === '84') ||
97
+ (type === 'ch' && enumTypeGenerateurId === '119')) &&
98
+ de.tv_generateur_combustion_id
99
+ ) {
100
+ row = tv('generateur_combustion', {
101
+ tv_generateur_combustion_id: de.tv_generateur_combustion_id
102
+ });
103
+ console.warn(`
104
+ Le générateur ${de.description} est caractérisé 'système collectif par défaut'.
105
+ Utilisation de tv_generateur_combustion_id pour récupération des informations techniques du générateur.
106
+ `);
107
+ } else {
108
+ // Calcul de la puissance nominale si non définie
109
+ if (!di.pn) {
110
+ di.pn = (1.2 * GV * (19 - tbase)) / 0.95 ** 3;
111
+ }
112
+
113
+ let matcher = {};
114
+ matcher[typeGenerateurKey] = enumTypeGenerateurId;
115
+ matcher.critere_pn = criterePn(di.pn / (de.ratio_virtualisation * 1000), matcher);
116
+
117
+ row = tv('generateur_combustion', matcher);
118
+
119
+ /**
120
+ * Si l'identifiant du générateur à combustion utilisé n'est pas le bon, avertissement
121
+ */
122
+ if (
123
+ bug_for_bug_compat &&
124
+ type === 'ecs' &&
125
+ row.tv_generateur_combustion_id !== de.tv_generateur_combustion_id
126
+ ) {
127
+ const rowDpe = tv('generateur_combustion', {
128
+ tv_generateur_combustion_id: de.tv_generateur_combustion_id
129
+ });
130
+
131
+ // Si tv_generateur_combustion_id utilisé n'est pas
132
+ if (
133
+ rowDpe &&
134
+ (!rowDpe.enum_type_generateur_ecs_id ||
135
+ !rowDpe.enum_type_generateur_ecs_id.split('|').includes(de.enum_type_generateur_ecs_id))
136
+ ) {
137
+ console.error(`
138
+ Le DPE utilise les caractéristiques liées à tv_generateur_combustion_id = '${de.tv_generateur_combustion_id}' qui ne correspond pas au
139
+ générateur ECS enum_type_generateur_ecs_id = '${de.enum_type_generateur_ecs_id}'. Les données utilisées par le DPE et les résultats
140
+ qui en découlent sont probablement erronés.
141
+ `);
142
+ }
143
+ }
144
+ }
145
+
146
+ if (!row) {
147
+ console.error(
148
+ 'Pas de valeur forfaitaire trouvée pour le générateur à combustion ${de.description}'
149
+ );
150
+ return;
151
+ }
152
+
153
+ de.tv_generateur_combustion_id = Number(row.tv_generateur_combustion_id);
154
+
155
+ const E = E_tab[de.presence_ventouse];
156
+ const F = F_tab[de.presence_ventouse];
157
+
158
+ /**
159
+ * Si la consommation ECS est obtenue par virtualisation du générateur collectif pour les besoins individuels
160
+ * la puissance nominale est obtenu à partir de la puissance nominale du générateur collectif multiplié par le
161
+ * ratio de virtualisation
162
+ * 17.2.1 - Génération d’un DPE à l’appartement / Traitement des usages collectifs
163
+ */
164
+ if (![3, 4, 5].includes(methodeSaisie)) {
165
+ if (row.rpn) {
166
+ di.rpn = excel_to_js_exec(row.rpn, di.pn / (de.ratio_virtualisation || 1), E, F) / 100;
167
+ }
168
+ if (type === 'ch' && row.rpint) {
169
+ di.rpint = excel_to_js_exec(row.rpint, di.pn / (de.ratio_virtualisation || 1), E, F) / 100;
170
+ }
171
+ }
172
+
173
+ if (![4, 5].includes(methodeSaisie)) {
174
+ if (row.qp0_perc) {
175
+ const qp0_calc = excel_to_js_exec(row.qp0_perc, di.pn / (de.ratio_virtualisation || 1), E, F);
176
+ // Certaines chaudières ont un qp0 en % de pn, d'autres ont des valeurs constantes
177
+ di.qp0 = row.qp0_perc.includes('Pn')
178
+ ? qp0_calc * 1000 * (de.ratio_virtualisation || 1)
179
+ : row.qp0_perc.includes('%')
180
+ ? qp0_calc * di.pn
181
+ : qp0_calc * 1000;
182
+ } else {
183
+ di.qp0 = 0;
184
+ }
185
+ }
186
+
187
+ if (methodeSaisie === 1 || !di.pveilleuse) {
188
+ di.pveil = Number(row.pveil) || 0;
189
+ } else {
190
+ di.pveil = di.pveilleuse || 0;
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Mise à jour du type de générateur si besoin
196
+ * @param dpe {FullDpe}
197
+ * @param de {Donnee_entree}
198
+ * @param type {'ch' | 'ecs'}
199
+ */
200
+ export function updateGenerateurCombustion(dpe, de, type) {
201
+ updateGenerateurBouilleurs(dpe, de, type);
202
+ updateGenerateurChaudieres(dpe, de, type);
203
+ updateGenerateurPacs(dpe, de, type);
204
+ addInfosFromFichesTechniques(dpe, de);
205
+ }
206
+
207
+ /**
208
+ * Récupération d'informations complémentaires issues des fiches techniques pour les générateurs
209
+ *
210
+ * @param dpe {FullDpe}
211
+ * @param de {Donnee_entree}
212
+ */
213
+ function addInfosFromFichesTechniques(dpe, de) {
214
+ // Récupération de la présence ou non d'un système de ventilation
215
+ const ficheTechnique = getFicheTechnique(
216
+ dpe,
217
+ '8',
218
+ 'Présence ventilateur / dispositif circulation air dans circuit combustion',
219
+ [de.description]
220
+ )?.valeur;
221
+
222
+ if (ficheTechnique && ficheTechnique === 'oui') {
223
+ de.presenceVentilateur = 1;
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Vérifier que les informations du générateur ECS sont bien les mêmes que celles du générateur de chauffage
229
+ * Dans le cas d'une génération mixte, le type du générateur doit être le même
230
+ * @param dpe {FullDpe}
231
+ * @param de {Donnee_entree}
232
+ * @param typeGenerateurKey {string}
233
+ * @returns {string}
234
+ */
235
+ function checkEcsVsChauffageForMixteGeneration(dpe, de, typeGenerateurKey) {
236
+ const ecsGenerateurId = de[typeGenerateurKey];
237
+
238
+ /**
239
+ * Si le générateur ECS est un générateur par défaut, pas d'information assez précise pour redresser la donnée
240
+ *
241
+ * 78 - autre système à combustion gaz
242
+ * 79 - autre système à combustion fioul
243
+ * 80 - autre système à combustion bois
244
+ * 81 - autre système à combustion autres energies fossiles (charbon,pétrole etc…)
245
+ * 82 - autre système thermodynamique électrique
246
+ * 83 - autre système thermodynamique gaz
247
+ */
248
+ if (['78', '79', '80', '81', '82', '83'].includes(de[`previous_${typeGenerateurKey}`])) {
249
+ return ecsGenerateurId;
250
+ }
251
+
252
+ /**
253
+ * @type {InstallationChauffageItem[]}
254
+ */
255
+ const installationsCh = dpe.logement.installation_chauffage_collection.installation_chauffage;
256
+
257
+ // Récupération des générateurs de chauffage ayant pour usage ECS + Chauffage également
258
+ const generateursChMixtes = installationsCh.reduce((acc, ch) => {
259
+ return acc.concat(
260
+ ch.generateur_chauffage_collection.generateur_chauffage.filter(
261
+ (value) => value.donnee_entree.enum_usage_generateur_id === '3'
262
+ )
263
+ );
264
+ }, []);
265
+
266
+ if (generateursChMixtes.length) {
267
+ const firstChGenerateurMixte = generateursChMixtes[0];
268
+ const firstChGenerateurMixteId =
269
+ firstChGenerateurMixte.donnee_entree.enum_type_generateur_ch_id;
270
+ const typeGenerateurEcs = enums.type_generateur_ecs;
271
+ const typeGenerateurCh = enums.type_generateur_ch;
272
+
273
+ const ecsGenerateurType = typeGenerateurEcs[ecsGenerateurId];
274
+ const chGenerateurType = typeGenerateurCh[firstChGenerateurMixteId];
275
+
276
+ // Si les 2 générateurs n'ont pas le même type
277
+ if (ecsGenerateurType !== chGenerateurType) {
278
+ // Recherche de l'identifiant du générateur ECS identique au générateur de chauffage
279
+ const newEcsGenerateurId = Object.keys(typeGenerateurEcs).find(
280
+ (key) => typeGenerateurEcs[key] === typeGenerateurCh[firstChGenerateurMixteId]
281
+ );
282
+
283
+ if (newEcsGenerateurId) {
284
+ console.error(`
285
+ Le générateur mixte ECS + CH identifié pour la génération ECS '${ecsGenerateurType}' n'est pas le même que celui identifié pour le générateur de chauffage '${chGenerateurType}'.
286
+ On conserve le type de générateur de chauffage '${chGenerateurType}' pour la suite des calculs ECS.
287
+ `);
288
+
289
+ return newEcsGenerateurId;
290
+ }
291
+ }
292
+ }
293
+
294
+ return ecsGenerateurId;
295
+ }
@@ -0,0 +1,173 @@
1
+ import getFicheTechnique from './ficheTechnique.js';
2
+
3
+ /**
4
+ * Pour les générateurs "poêles à bois bouilleur", les calculs sont faits comme pour les chaudières bois
5
+ * @param dpe {FullDpe}
6
+ * @param de {Donnee_entree}
7
+ * @param type {'ch' | 'ecs'}
8
+ */
9
+ export function updateGenerateurBouilleurs(dpe, de, type) {
10
+ let ids;
11
+
12
+ /**
13
+ * 13.1 Inserts et poêles
14
+ * Les poêles à bois bouilleur sont traités comme des chaudières bois
15
+ * L'année d'installation du générateur est récupéré, si définit, depuis les fiches techniques
16
+ * Le générateur "chaudières bois" pour la même période est alors utilisé
17
+ *
18
+ * enum_type_generateur_ecs_id
19
+ * 13 - poêle à bois bouilleur bûche installé avant 2012
20
+ * 14 - poêle à bois bouilleur bûche installé à partir de 2012
21
+ * 115 - poêle à bois bouilleur granulés installé avant 2012
22
+ * 116 - poêle à bois bouilleur granulés installé à partir de 2012
23
+ */
24
+ if (type === 'ecs') {
25
+ // Ids des chaudières bois équivalentes pour les différentes périodes d'installation
26
+ ids = {
27
+ 13: {
28
+ 1948: '15',
29
+ 1978: '16',
30
+ 1995: '17',
31
+ 2004: '18',
32
+ 2013: '19',
33
+ 2018: '20',
34
+ 2019: '21'
35
+ },
36
+ 14: {
37
+ 1948: '15',
38
+ 1978: '16',
39
+ 1995: '17',
40
+ 2004: '18',
41
+ 2013: '19',
42
+ 2018: '20',
43
+ 2019: '21'
44
+ },
45
+ 115: {
46
+ 1948: '29',
47
+ 1978: '30',
48
+ 1995: '31',
49
+ 2004: '32',
50
+ 2013: '33',
51
+ 2018: '33',
52
+ 2019: '34'
53
+ },
54
+ 116: {
55
+ 1948: '29',
56
+ 1978: '30',
57
+ 1995: '31',
58
+ 2004: '32',
59
+ 2013: '33',
60
+ 2018: '33',
61
+ 2019: '34'
62
+ }
63
+ };
64
+ } else {
65
+ /**
66
+ * enum_type_generateur_ch_id
67
+ * 48 - poêle à bois bouilleur bûche installé avant 2012
68
+ * 49 - poêle à bois bouilleur bûche installé à partir de 2012
69
+ * 140 - poêle à bois bouilleur granulés installé avant 2012
70
+ * 141 - poêle à bois bouilleur granulés installé à partir de 2012
71
+ */
72
+ // Ids des chaudières bois équivalentes pour les différentes périodes d'installation
73
+ ids = {
74
+ 48: {
75
+ 1948: '55',
76
+ 1978: '56',
77
+ 1995: '57',
78
+ 2004: '58',
79
+ 2013: '59',
80
+ 2018: '60',
81
+ 2019: '61'
82
+ },
83
+ 49: {
84
+ 1948: '55',
85
+ 1978: '56',
86
+ 1995: '57',
87
+ 2004: '58',
88
+ 2013: '59',
89
+ 2018: '60',
90
+ 2019: '61'
91
+ },
92
+ 140: {
93
+ 1948: '69',
94
+ 1978: '70',
95
+ 1995: '71',
96
+ 2004: '72',
97
+ 2013: '73',
98
+ 2018: '73',
99
+ 2019: '74'
100
+ },
101
+ 141: {
102
+ 1948: '69',
103
+ 1978: '70',
104
+ 1995: '71',
105
+ 2004: '72',
106
+ 2013: '73',
107
+ 2018: '73',
108
+ 2019: '74'
109
+ }
110
+ };
111
+ }
112
+
113
+ updateGenerateurBouilleur(dpe, ids, de, type);
114
+ }
115
+
116
+ /**
117
+ * Récupération du générateur équivalent à utiliser à la place du générateur décrit
118
+ * La période du générateur équivalent est choisie par rapport à la date d'installation du générateur décrit
119
+ * Ex:
120
+ * - Pour un poêle à bois bouilleur granulés installé en 2000, on prendra la chaudière bois granulés 1995-2003
121
+ * - Pour un poêle à bois bouilleur bûche installé avant 1948, on prendra la chaudière bois bûche avant 1978
122
+ * @param dpe {FullDpe}
123
+ * @param ids
124
+ * @param de {Donnee_entree}
125
+ * @param type {'ch' | 'ecs'}
126
+ */
127
+ function updateGenerateurBouilleur(dpe, ids, de, type) {
128
+ const enumType = `enum_type_generateur_${type}_id`;
129
+ const generateurId = de[enumType];
130
+
131
+ const steps = Object.keys(ids);
132
+
133
+ if (steps.includes(generateurId)) {
134
+ const values = ids[generateurId];
135
+
136
+ // Récupération de l'année d'installation du système ECS ou Chauffage dans les fiches techniques
137
+ const ficheTechnique = getFicheTechnique(dpe, '7', 'année', ['bouilleur'])?.valeur;
138
+
139
+ /**
140
+ * Par défaut:
141
+ * - Les poêles à bois bouilleur installées à partir de 2012 sont traités comme des chaudières bois installées entre 2004 et
142
+ * 2012.
143
+ * - Les poêles à bois bouilleur installées avant 2012 sont traités comme des chaudières bois installées entre 1978 et 1994.
144
+ */
145
+ let newGenerateurId = generateurId === 13 ? values[1978] : values[2004];
146
+
147
+ if (ficheTechnique) {
148
+ if (ficheTechnique.toString().toLowerCase() === 'avant 1948') {
149
+ newGenerateurId = values[1948];
150
+ } else {
151
+ const installationDate = parseInt(ficheTechnique, 10);
152
+
153
+ if (installationDate >= 2019) {
154
+ newGenerateurId = values[2019];
155
+ } else if (installationDate >= 2018) {
156
+ newGenerateurId = values[2018];
157
+ } else if (installationDate >= 2013) {
158
+ newGenerateurId = values[2013];
159
+ } else if (installationDate >= 2004) {
160
+ newGenerateurId = values[2004];
161
+ } else if (installationDate >= 1995) {
162
+ newGenerateurId = values[1995];
163
+ } else if (installationDate >= 1978) {
164
+ newGenerateurId = values[1978];
165
+ } else if (installationDate >= 1948) {
166
+ newGenerateurId = values[1948];
167
+ }
168
+ }
169
+ }
170
+
171
+ de[enumType] = newGenerateurId;
172
+ }
173
+ }
@@ -0,0 +1,195 @@
1
+ import enums from './enums.js';
2
+ import { bug_for_bug_compat, requestInput, requestInputID, tv } from './utils.js';
3
+
4
+ const coef_pond = {
5
+ 0.05: 0.1,
6
+ 0.15: 0.25,
7
+ 0.25: 0.2,
8
+ 0.35: 0.15,
9
+ 0.45: 0.1,
10
+ 0.55: 0.1,
11
+ 0.65: 0.05,
12
+ 0.75: 0.025,
13
+ 0.85: 0.025,
14
+ 0.95: 0
15
+ };
16
+
17
+ const K = {
18
+ électricité: 1,
19
+ 'gaz naturel': 1.11,
20
+ gpl: 1.09,
21
+ 'fioul domestique': 1.07,
22
+ 'bois – bûches': 1.08,
23
+ 'bois – granulés (pellets) ou briquettes': 1.08,
24
+ 'bois – plaquettes forestières': 1.08,
25
+ 'bois – plaquettes d’industrie': 1.08,
26
+ 'réseau de chauffage urbain': 1,
27
+ charbon: 1.04,
28
+ propane: 1.11,
29
+ butane: 1.11,
30
+ "électricité d'origine renouvelable utilisée dans le bâtiment": undefined,
31
+ 'autre combustible fossile': undefined,
32
+ 'réseau de froid urbain': undefined
33
+ };
34
+
35
+ export function tv_temp_fonc_30_100(di, de, du, em_ch, ac) {
36
+ for (const em of em_ch) {
37
+ const em_ch_de = em.donnee_entree;
38
+ const em_ch_du = em.donnee_utilisateur;
39
+ const matcher = {
40
+ type_generateur_ch_id: de.enum_type_generateur_ch_id,
41
+ enum_temp_distribution_ch_id: requestInputID(em_ch_de, em_ch_du, 'temp_distribution_ch'),
42
+ periode_emetteurs: requestInput(em_ch_de, em_ch_du, 'periode_installation_emetteur')
43
+ };
44
+
45
+ if (!matcher.periode_emetteurs) {
46
+ if (ac < 1981) matcher.periode_emetteurs = 'avant 1981';
47
+ else if (ac < 2000) matcher.periode_emetteurs = 'entre 1981 et 2000';
48
+ else matcher.periode_emetteurs = 'après 2000';
49
+ }
50
+
51
+ const row_30 = tv('temp_fonc_30', matcher);
52
+ const row_100 = tv('temp_fonc_100', matcher);
53
+
54
+ if (row_30) {
55
+ if (!di.temp_fonc_30 || Number(row_30.temp_fonc_30) > di.temp_fonc_30) {
56
+ de.tv_temp_fonc_30_id = row_30.tv_temp_fonc_30_id;
57
+ di.temp_fonc_30 = Number(row_30.temp_fonc_30);
58
+ }
59
+ } else {
60
+ console.error('!! pas de valeur forfaitaire trouvée pour temp_fonc_30 !!');
61
+ }
62
+
63
+ if (row_100) {
64
+ if (!di.temp_fonc_100 || Number(row_100.temp_fonc_100) > di.temp_fonc_100) {
65
+ de.tv_temp_fonc_100_id = row_100.tv_temp_fonc_100_id;
66
+ di.temp_fonc_100 = Number(row_100.temp_fonc_100);
67
+ }
68
+ } else {
69
+ console.error('!! pas de valeur forfaitaire trouvée pour temp_fonc_100 !!');
70
+ }
71
+ }
72
+ }
73
+
74
+ function Tch_xfinal(x, Cdimref) {
75
+ return Math.min(1, x / Cdimref);
76
+ }
77
+
78
+ function QPx(x, de, di) {
79
+ const type_gen_ch = enums.type_generateur_ch[de.enum_type_generateur_ch_id];
80
+ const type_energie = enums.type_energie[de.enum_type_energie_id];
81
+ const k = K[type_energie];
82
+ const pn = di.pn / 1000;
83
+ const rpn = (100 * di.rpn) / k;
84
+ const rpint = (100 * di.rpint) / k;
85
+ let qp0 = (di.qp0 * k) / 1000;
86
+ const tf30 = di.temp_fonc_30;
87
+ const tf100 = di.temp_fonc_100;
88
+
89
+ let QPx;
90
+ if (type_gen_ch.includes('radiateur à gaz')) {
91
+ QPx = ((1.04 * (100 - rpn)) / rpn) * pn * x;
92
+ } else if (type_gen_ch.includes('chaudière bois') || type_gen_ch.includes('chaudière charbon')) {
93
+ const QP50 = (0.5 * pn * (100 - rpint)) / rpint;
94
+ const QP100 = (pn * (100 - rpn)) / rpn;
95
+ if (x < 0.5) QPx = 0.15 * qp0 + ((QP50 - 0.15 * qp0) * x) / 0.5;
96
+ else QPx = 2 * QP50 - QP100 + ((QP100 - QP50) * x) / 0.5;
97
+ } else if (type_gen_ch.includes('chaudière')) {
98
+ let tf;
99
+ if (de.presence_regulation_combustion) tf = tf30;
100
+ else tf = tf100;
101
+ let QP30, a, b;
102
+ if (type_gen_ch.includes('basse température')) {
103
+ a = 0.1;
104
+ b = 40;
105
+ } else if (type_gen_ch.includes('condensation')) {
106
+ a = 0.2;
107
+ b = 33;
108
+ } else {
109
+ a = 0.1;
110
+ b = 50;
111
+ }
112
+ QP30 = (0.3 * pn * (100 - (rpint + a * (b - tf)))) / (rpint + a * (b - tf));
113
+ const QP100 = (pn * (100 - (rpn + 0.1 * (70 - tf100)))) / (rpn + 0.1 * (70 - tf100));
114
+ const QP15 = QP30 / 2;
115
+ if (type_gen_ch.includes('basse température') || type_gen_ch.includes('condensation')) {
116
+ if (x < 0.15) QPx = 0.15 * qp0 + ((QP15 - 0.15 * qp0) * x) / 0.15;
117
+ else if (x < 0.3) QPx = QP15 + ((QP30 - QP15) * (x - 0.15)) / 0.15;
118
+ else QPx = QP30 + ((QP100 - QP30) * (x - 0.3)) / 0.7;
119
+ } else {
120
+ if (x < 0.3) QPx = 0.15 * qp0 + ((QP30 - 0.15 * qp0) * x) / 0.3;
121
+ else QPx = QP30 + ((QP100 - QP30) * (x - 0.3)) / 0.7;
122
+ }
123
+ } else if (type_gen_ch.includes('générateur à air chaud')) {
124
+ // Change QP0 to be in decimal
125
+ di.qp0 = di.qp0 / 100;
126
+ qp0 = (di.qp0 * k) / 1000;
127
+
128
+ const QP50 = (0.5 * pn * (100 - rpint)) / rpint;
129
+ const QP100 = (pn * (100 - rpn)) / rpn;
130
+ if (x < 0.5) QPx = 0.15 * qp0 + ((QP50 - 0.15 * qp0) * x) / 0.5;
131
+ else QPx = 2 * QP50 - QP100 + ((QP100 - QP50) * x) / 0.5;
132
+ } else {
133
+ console.warn('!! type_generateur_ch n’est pas connu !!');
134
+ }
135
+ /* console.warn('QPx', QPx) */
136
+ return QPx;
137
+ }
138
+
139
+ function Px(x, di, Cdimref) {
140
+ const Px = (di.pn / 1000) * Tch_xfinal(x, Cdimref);
141
+ return Px;
142
+ }
143
+
144
+ function Pfou(x, di, Cdimref) {
145
+ // find coef_pond[x] in coef_pond where x is closest to x_final
146
+ return Px(x, di, Cdimref) * coef_pond[x];
147
+ }
148
+
149
+ function Pcons(x, de, di, Cdimref) {
150
+ const x_final = Tch_xfinal(x, Cdimref);
151
+ return Pfou(x, di, Cdimref) * (1 + QPx(x_final, de, di) / Px(x, di, Cdimref));
152
+ }
153
+
154
+ export function calc_generateur_combustion_ch(dpe, di, de, du) {
155
+ if (bug_for_bug_compat) {
156
+ if (di.qp0 < 1) {
157
+ di.qp0 *= 1000;
158
+ console.warn(
159
+ `Correction di.qp0 pour le générateur de chauffage ${de.description}. Passage de la valeur en W`
160
+ );
161
+ }
162
+ }
163
+
164
+ // La puissance de la veilleuse est à prendre en compte seulement si elle est présente dans l'installation
165
+ if (!di.pveilleuse) {
166
+ di.pveil = 0;
167
+ }
168
+
169
+ const Cdimref = du.cdimref || 0;
170
+ const Cdimref_dep = du.cdimrefDep || 0;
171
+ const Pmfou = Object.keys(coef_pond).reduce((acc, x) => acc + Pfou(x, di, Cdimref), 0);
172
+ const Pmcons = Object.keys(coef_pond).reduce((acc, x) => acc + Pcons(x, de, di, Cdimref), 0);
173
+ const Pmfou_dep = Object.keys(coef_pond).reduce((acc, x) => acc + Pfou(x, di, Cdimref_dep), 0);
174
+ const Pmcons_dep = Object.keys(coef_pond).reduce(
175
+ (acc, x) => acc + Pcons(x, de, di, Cdimref_dep),
176
+ 0
177
+ );
178
+ const type_energie = requestInput(de, du, 'type_energie');
179
+ const k = K[type_energie];
180
+
181
+ // Pveil and QP0 are in kW
182
+ const Pveil = di.pveil / 1000;
183
+ const QP0 = di.qp0 / 1000;
184
+
185
+ const rg_pcs = Pmfou / (Pmcons + 0.45 * QP0 + Pveil);
186
+ const rg_pcs_dep = Pmfou_dep / (Pmcons_dep + 0.45 * QP0 + Pveil);
187
+
188
+ const rg_pci = rg_pcs * k;
189
+ const rg_pci_dep = rg_pcs_dep * k;
190
+ di.rendement_generation = rg_pci;
191
+
192
+ // for Ich
193
+ di.rg = rg_pci;
194
+ di.rg_dep = rg_pci_dep;
195
+ }