UNPKG

@open3cl/engine

Version:

Open Source 3CL-DPE engine

283 lines (246 loc) 9.55 kB
import enums from './enums.js'; import { requestInput, requestInputID, tv, tvColumnIDs } from './utils.js'; import { conso_aux_distribution_ch, conso_aux_gen } from './15_conso_aux.js'; import { conso_ch } from './9_conso_ch.js'; import { calc_generateur_combustion_ch } from './13.2_generateur_combustion_ch.js'; import { scopOrCop } from './12.4_pac.js'; import { updateGenerateurCombustion } from './13.2_generateur_combustion.js'; const ENUM_MATERIAUX_STRUCTURE_MUR_ANCIEN_IDS = ['2', '3', '4', '6', '8', '9', '14', '21']; const ENUM_CLASSES_INERTIE_LOURDES_IDS = ['1', '2']; function pertes_gen_ch(Bch_hp_j, pn) { return (1.3 * Bch_hp_j) / (0.3 * pn); } function pertes_gen_ecs(nrefj) { return (nrefj * 1790) / 8760; } export function calc_Qrec_gen_j(gen_ch, nrefj, Bch_hp_j) { const de = gen_ch.donnee_entree; const du = gen_ch.donnee_utilisateur || {}; const di = gen_ch.donnee_intermediaire; if (de.position_volume_chauffe === 0) return 0; const type_gen_ch = enums.type_generateur_ch[de.enum_type_generateur_ch_id]; if (type_gen_ch.includes('générateur à air chaud')) return 0; let Cper; if (de.presence_ventouse === 1) Cper = 0.75; else Cper = 0.5; const usage_generateur = requestInput(de, du, 'usage_generateur'); let Dperj; if (usage_generateur === 'chauffage') Dperj = Math.min(nrefj, pertes_gen_ch(Bch_hp_j, di.pn)); else if (usage_generateur === 'ecs') Dperj = pertes_gen_ecs(nrefj); else if (usage_generateur === 'chauffage + ecs') { Dperj = Math.min(nrefj, pertes_gen_ch(Bch_hp_j, di.pn) + pertes_gen_ecs(nrefj)); } gen_ch.donnee_utilisateur = du; return 0.48 * Cper * di.qp0 * Dperj || 0; } function tv_rendement_generation(di, de, du) { const matcher = { enum_type_generateur_ch_id: requestInputID(de, du, 'type_generateur_ch') }; const row = tv('rendement_generation', matcher, de); if (row) { di.rendement_generation = Number(row.rg); di.rg = di.rendement_generation; di.rg_dep = di.rendement_generation; de.tv_rendement_generation_id = Number(row.tv_rendement_generation_id); } else { console.error('!! pas de valeur forfaitaire trouvée pour rendement_generation ch !!'); } } export function type_generateur_ch(di, de, du, usage_generateur) { let type_generateur; if (usage_generateur === 'chauffage') { type_generateur = requestInputID(de, du, 'type_generateur_ch'); } else if (usage_generateur === 'chauffage + ecs') { const generateur_ecs = enums.type_generateur_ecs; const generateur_ch = enums.type_generateur_ch; const generateurs_ch_ecs = Object.keys(generateur_ch).reduce((acc, key) => { const gen_ch = generateur_ch[key]; if (Object.values(generateur_ecs).includes(gen_ch)) acc[key] = gen_ch; return acc; }, {}); type_generateur = requestInputID(de, du, 'type_generateur_ch', Object.keys(generateurs_ch_ecs)); } else { console.warn("!! usage_generateur n'est pas 'chauffage' ou 'chauffage + ecs' !!"); } return type_generateur; } /** * Récupération du type de générateur * @param dpe {FullDpe} * @param de {Donnee_entree} * @param di {Donnee_intermediaire} * @param du {Object} */ export function checkForGeneratorType(dpe, de, di, du) { const combustion_ids = tvColumnIDs('generateur_combustion', 'type_generateur_ch'); const pac_ids = tvColumnIDs('scop', 'type_generateur_ch'); // Mise à jour du type de générateur si besoin updateGenerateurCombustion(dpe, de, 'ch'); const usage_generateur = requestInput(de, du, 'usage_generateur'); const type_gen_ch_id = type_generateur_ch(di, de, du, usage_generateur); let isPacGenerator = pac_ids.includes(type_gen_ch_id); let isCombustionGenerator = combustion_ids.includes(type_gen_ch_id); /** * Pour le type de chauffage 119 - système collectif par défaut en abscence d'information : chaudière fioul pénalisante, * détection en fonction des données d'entrées du type de générateur pour calculer les rendements de l'installation * * Si présence de tv_generateur_combustion_id dans les données d'entrée alors générateur à combustion * Si présence de tv_scop_id dans les données d'entrée alors générateur pompe à chaleur */ if (type_gen_ch_id === '119') { isPacGenerator = false; isCombustionGenerator = false; if (de.tv_generateur_combustion_id) { const row = tv('generateur_combustion', { tv_generateur_combustion_id: de.tv_generateur_combustion_id }); if (row) { // On prend par défaut le premier type de générateur pour effectuer les calculs de rendement const typeGenerateurCh = row.enum_type_generateur_ch_id?.split('|'); if (typeGenerateurCh && typeGenerateurCh.length) { de.enum_type_generateur_ch_id = typeGenerateurCh[0]; } } isCombustionGenerator = true; } else if (de.tv_scop_id) { isPacGenerator = true; } else { const row = tv('rendement_generation', { tv_rendement_generation_id: de.tv_rendement_generation_id }); if (row) { // On prend par défaut le premier type de générateur pour effectuer les calculs de rendement const typeGenerateurCh = row.enum_type_generateur_ch_id?.split('|'); if (typeGenerateurCh && typeGenerateurCh.length) { de.enum_type_generateur_ch_id = typeGenerateurCh[0]; } } } } du.isPacGenerator = isPacGenerator; du.isCombustionGenerator = isCombustionGenerator; } export function calc_generateur_ch( dpe, gen_ch, _pos, em_ch, cfg_ch, bch, bch_dep, GV, Sh, hsp, ca_id, zc_id, ilpa, tbase, besoin_ch_mois, s_chauffee_inst, gen_ch_list ) { const de = gen_ch.donnee_entree; const du = gen_ch.donnee_utilisateur || {}; const di = gen_ch.donnee_intermediaire || {}; if (du.isPacGenerator) { let em; // Si un seul émetteur de chauffage décrit, on considère que cet émetteur est relié au générateur de chauffage if (em_ch.length === 1) { em = em_ch[0]; } else { const gen_lge_id = requestInputID(de, du, 'lien_generateur_emetteur'); em = em_ch.find((em) => em.donnee_entree.enum_lien_generateur_emetteur_id === gen_lge_id); } if (em) { const ed_id = em.donnee_entree.enum_type_emission_distribution_id; scopOrCop(di, de, du, zc_id, ed_id, 'ch'); } else { console.error( `Emetteur de chauffage non trouvé pour le générateur ${de.description}, les valeurs intermédiaires saisies sont prises en compte` ); di.rg = di.scop || di.cop; di.rg_dep = di.scop || di.cop; } } else if (du.isCombustionGenerator) { calc_generateur_combustion_ch(dpe, di, de, du); } else { tv_rendement_generation(di, de, du); } conso_aux_gen(di, de, 'ch', bch, bch_dep, Sh); /** * 15 Calcul des consommations d’auxiliaires des installations de chauffage (Caux_ch) et d’ECS (Caux_ecs) */ if (hasConsoForAuxDistribution(de.enum_type_generateur_ch_id)) { conso_aux_distribution_ch(em_ch, de, di, du, Sh, zc_id, ca_id, ilpa, GV); } const paroi_ancienne = isParoisAncienneInertieLourde(dpe); conso_ch( di, de, du, _pos, cfg_ch, em_ch, GV, Sh, hsp, bch, bch_dep, tbase, paroi_ancienne, ca_id, zc_id, besoin_ch_mois, s_chauffee_inst, gen_ch_list ); gen_ch.donnee_intermediaire = di; gen_ch.donnee_utilisateur = du; } /** * 15 Calcul des consommations d’auxiliaires des installations de chauffage (Caux_ch) et d’ECS (Caux_ecs) * * Les consommations des auxiliaires de distribution de chauffage et d’ECS sont prises nulles pour les installations * individuelles en l’absence d’un circulateur externe au générateur. On exclut donc les générateurs suivants : * * >= 4 - exclusion des PAC air / air * >= 20 && <= 47 - exclusion des poêles * 53, 54 - exclusion des radiateurs gaz * >= 98 && <= 105 - exclusion des émetteurs à effet joule, radiateurs électriques, plafonds / planchers électriques * */ export function hasConsoForAuxDistribution(enum_type_generateur_ch_id) { return ( enum_type_generateur_ch_id >= 106 || (enum_type_generateur_ch_id >= 55 && enum_type_generateur_ch_id <= 97) || [48, 49, 50, 51, 52].includes(enum_type_generateur_ch_id) || (enum_type_generateur_ch_id >= 4 && enum_type_generateur_ch_id <= 19) ); } /** * 18.3 Cas des bâtiments à inertie lourde, constitués de parois anciennes * * Afin d’être considéré comme un bâtiment à inertie lourde, constitués de parois anciennes, le bâtiment doit : * * Etre constitué de murs en matériaux anciens : terre, pierre, brique ancienne, colombage, … ; * * Avoir une inertie lourde. * * En présence de plusieurs types de parois, le bâtiment sera considéré comme constitué de parois anciennes si la surface * de parois anciennes est majoritaire. * @param dpe {FullDpe} */ function isParoisAncienneInertieLourde(dpe) { const murs = dpe.logement.enveloppe.mur_collection.mur.filter( (mur) => mur.donnee_intermediaire.b > 0 ); const nbTotalMurs = murs.length; const nbMursAnciens = murs.filter((mur) => ENUM_MATERIAUX_STRUCTURE_MUR_ANCIEN_IDS.includes( mur.donnee_entree.enum_materiaux_structure_mur_id ) ).length; const isInertieLourde = ENUM_CLASSES_INERTIE_LOURDES_IDS.includes( dpe.logement.enveloppe.inertie.enum_classe_inertie_id ); return isInertieLourde && nbMursAnciens / nbTotalMurs >= 0.5; }