@open3cl/engine
Version:
Open Source 3CL-DPE engine
363 lines (316 loc) • 11.6 kB
JavaScript
import { tvs as tv } from '../../../../tv-v2.js';
import { getRange } from '../../../../utils.js';
import { logger } from '../../../../core/util/logger/log-service.js';
import { TvStore } from './../tv.store.js';
import enums from '../../../../enums.js';
/**
* Accès aux données des tables de valeurs pour les baies vitrées
*/
export class BaieVitreeTvStore extends TvStore {
/**
* Coefficient de transmission thermique du vitrage (W/(m².K))
*
* @param enumTypeVitrageId {string}
* @param enumTypeGazLameId {string|undefined}
* @param enumInclinaisonVitrageId {string|undefined}
* @param vitrageVir {number|undefined}
* @param epaisseurLame {number|undefined}
* @return {number|undefined}
*/
getUg(enumTypeVitrageId, enumTypeGazLameId, enumInclinaisonVitrageId, vitrageVir, epaisseurLame) {
const ug = tv['ug'].find(
(v) =>
v.enum_type_vitrage_id.split('|').includes(enumTypeVitrageId) &&
(!enumTypeGazLameId || v.enum_type_gaz_lame_id?.split('|').includes(enumTypeGazLameId)) &&
(!enumInclinaisonVitrageId ||
v.enum_inclinaison_vitrage_id?.split('|').includes(enumInclinaisonVitrageId)) &&
(!vitrageVir || parseInt(vitrageVir) === parseInt(v.vitrage_vir)) &&
(!epaisseurLame || parseFloat(v.epaisseur_lame) === epaisseurLame)
)?.ug;
if (!ug) {
logger.error(
`Pas de valeur forfaitaire ug pour enumTypeVitrageId:${enumTypeVitrageId}, enumTypeGazLameId:${enumTypeGazLameId}, enumInclinaisonVitrageId:${enumInclinaisonVitrageId}, vitrageVir:${vitrageVir}, epaisseurLame:${epaisseurLame}`
);
return;
}
return parseFloat(ug);
}
/**
* Épaisseurs disponibles pour les coefficients de transmission thermique du vitrage (W/(m².K))
*
* @return {number[]}
*/
getEpaisseurAvailableForUg() {
return [
...new Set(tv['ug'].map((value) => parseInt(value.epaisseur_lame) || 0).sort((a, b) => a - b))
];
}
/**
* Proportion d’énergie solaire incidente qui pénètre dans le logement par la paroi vitrée
*
* @param enumTypeVitrageId {string}
* @param enumTypeBaieId {string}
* @param enumTypeMateriauxMenuiserieId {string}
* @param vitrageVir {number|undefined}
* @param enumTypePoseId {string|undefined}
* @return {number|undefined}
*/
getSw(
enumTypeVitrageId,
enumTypeBaieId,
enumTypeMateriauxMenuiserieId,
vitrageVir,
enumTypePoseId
) {
const sw = tv['sw'].find(
(v) =>
(!v.enum_type_vitrage_id ||
v.enum_type_vitrage_id.split('|').includes(enumTypeVitrageId)) &&
v.enum_type_baie_id.split('|').includes(enumTypeBaieId) &&
v.enum_type_materiaux_menuiserie_id.split('|').includes(enumTypeMateriauxMenuiserieId) &&
(!vitrageVir || parseInt(vitrageVir) === parseInt(v.vitrage_vir)) &&
(!enumTypePoseId || v.enum_type_pose_id.split('|').includes(enumTypePoseId))
)?.sw;
if (!sw) {
logger.error(
`Pas de valeur forfaitaire sw pour enumTypeVitrageId:${enumTypeVitrageId}, enumTypeBaieId:${enumTypeBaieId}, enumTypeMateriauxMenuiserieId:${enumTypeMateriauxMenuiserieId}, vitrageVir:${vitrageVir}, enumTypePoseId:${enumTypePoseId}`
);
return;
}
return parseFloat(sw);
}
/**
* Coefficient de transmission thermique des fenêtres
*
* @param enumTypeVitrageId {string}
* @param enumTypeBaieId {string}
* @param enumTypeMateriauxMenuiserieId {string}
* @param ug {number|undefined}
* @return {number|undefined}
*/
getUw(enumTypeBaieId, enumTypeMateriauxMenuiserieId, ug) {
let uw;
/**
* Pas de notion de ug pour les parois polycarbonate ou verre
* enum_type_baie_id
* 1 - paroi en brique de verre pleine
* 2 - paroi en brique de verre creuse
* 3 - paroi en polycarbonnate
*/
if (['1', '2', '3'].includes(enumTypeBaieId)) {
uw = tv['uw'].find((v) => v.enum_type_baie_id.split('|').includes(enumTypeBaieId))?.uw;
} else {
/**
* 3.3.2 Coefficients Uw des fenêtres / portes-fenêtres
* Les Uw associés à des Ug non présents dans les tableaux peuvent être obtenus par interpolation ou
* extrapolation avec les deux Ug tabulés les plus proches.
*/
const ugValues =
tv['uw'].filter(
(v) =>
v.enum_type_baie_id.split('|').includes(enumTypeBaieId) &&
v.enum_type_materiaux_menuiserie_id.split('|').includes(enumTypeMateriauxMenuiserieId)
) || [];
let ug1, ug2;
if (ugValues.length) {
[ug1, ug2] = getRange(ug, [...new Set(ugValues.map((value) => value.ug).sort())]);
const uw1 = ugValues.find((value) => value.ug === ug1)?.uw || 0;
const uw2 = ugValues.find((value) => value.ug === ug2)?.uw || 0;
const delta_uw = Number(uw2) - Number(uw1);
const delta_ug = ug2 - ug1 || 0;
if (delta_ug === 0) {
uw = Number(uw1);
} else {
// Interpolation linéaire si upb n'est pas une valeur connue
uw = Number(uw1) + (delta_uw * (ug - ug1)) / delta_ug;
}
}
}
if (!uw) {
logger.error(
`Pas de valeur forfaitaire uw pour enumTypeBaieId:${enumTypeBaieId}, enumTypeMateriauxMenuiserieId:${enumTypeMateriauxMenuiserieId}, ug:${ug}`
);
return;
}
return parseFloat(uw);
}
/**
* La présence de volets aux fenêtres et portes-fenêtres leur apporte un supplément d’isolation avec une résistance
* additionnelle ΔR
*
* @param enumTypeFermetureId {string}
* @return {number|undefined}
*/
getDeltar(enumTypeFermetureId) {
const deltar = tv['deltar'].find((v) =>
v.enum_type_fermeture_id.split('|').includes(enumTypeFermetureId)
)?.deltar;
if (!deltar) {
logger.error(
`Pas de valeur forfaitaire deltar pour enumTypeFermetureId:${enumTypeFermetureId}`
);
return;
}
return parseFloat(deltar);
}
/**
* La présence de volets aux fenêtres et portes-fenêtres leur apporte un supplément d’isolation avec une résistance
* additionnelle ΔR
*
* @param enumTypeFermetureId {string}
* @param uw {number}
*
* @return {number|undefined}
*/
getUjn(enumTypeFermetureId, uw) {
let ujn;
/**
* 3.3.3 Coefficients Ujn des fenêtres/portes-fenêtres
* Dans la suite, les Ujn associés à des Uw non présents dans les tableaux peuvent être obtenus par interpolation ou
* extrapolation avec les deux Uw tabulés les plus proches.
*/
const deltar = this.getDeltar(enumTypeFermetureId);
const uwValues =
tv['ujn'].filter((v) => Number(v.deltar).toPrecision(2) === Number(deltar).toPrecision(2)) ||
[];
let uw1, uw2;
if (uwValues.length) {
[uw1, uw2] = getRange(uw, [...new Set(uwValues.map((value) => value.uw).sort())]);
const ujn1 =
uwValues.find((value) => Number(value.uw).toPrecision(2) === Number(uw1).toPrecision(2))
?.ujn || 0;
const ujn2 =
uwValues.find((value) => Number(value.uw).toPrecision(2) === Number(uw2).toPrecision(2))
?.ujn || 0;
const delta_ujn = Number(ujn2) - Number(ujn1);
const delta_uw = uw2 - uw1 || 0;
if (delta_uw === 0) {
ujn = Number(ujn1);
} else {
// Interpolation linéaire si uw n'est pas une valeur connue
ujn = Number(ujn1) + (delta_ujn * (uw - uw1)) / delta_uw;
}
if (!ujn) {
logger.error(
`Pas de valeur forfaitaire ujn pour enumTypeFermetureId:${enumTypeFermetureId}, uw:${uw}`
);
return;
}
return parseFloat(ujn);
}
}
/**
* Calcul de l’ombrage créé par un obstacle sur une paroi
*
* @param tvCoeffMasqueLointainNonHomogeneId {number}
* @return {number|undefined}
*/
getOmbre(tvCoeffMasqueLointainNonHomogeneId) {
const ombre = tv['coef_masque_lointain_non_homoge'].find(
(v) =>
parseInt(v.tv_coef_masque_lointain_non_homogene_id) ===
parseInt(tvCoeffMasqueLointainNonHomogeneId)
)?.omb;
if (!ombre) {
logger.error(
`Pas de valeur forfaitaire ombre pour tvCoeffMasqueLointainNonHomogeneId:${tvCoeffMasqueLointainNonHomogeneId}`
);
return;
}
return parseFloat(ombre);
}
/**
* Calcul de l'incidence d'un masque proche sur une paroi
*
* @param tvCoefMasqueProcheId {number}
* @return {number|undefined}
*/
getMasqueProche(tvCoefMasqueProcheId) {
const fe1 = tv['coef_masque_proche'].find(
(v) => parseInt(v.tv_coef_masque_proche_id) === parseInt(tvCoefMasqueProcheId)
)?.fe1;
if (!fe1) {
logger.error(`Pas de valeur fe1 pour tvCoefMasqueProcheId:${tvCoefMasqueProcheId}`);
return;
}
return parseFloat(fe1);
}
/**
* Calcul de l'incidence d'un masque lointain homogène sur une paroi
*
* @param tvCoefMasqueLointainHomogeneId {number}
* @return {number|undefined}
*/
getMasqueLointainHomogene(tvCoefMasqueLointainHomogeneId) {
const fe2 = tv['coef_masque_lointain_homogene'].find(
(v) =>
parseInt(v.tv_coef_masque_lointain_homogene_id) === parseInt(tvCoefMasqueLointainHomogeneId)
)?.fe2;
if (!fe2) {
logger.error(
`Pas de valeur fe2 pour tvCoefMasqueLointainHomogeneId:${tvCoefMasqueLointainHomogeneId}`
);
return;
}
return parseFloat(fe2);
}
/**
* Calcul des coefficients de réduction de température des espaces tampons
*
* @param zoneClimatique {string}
* @param enumCfgIsolationLncId {number}
* @return {number|undefined}
*/
getBver(zoneClimatique, enumCfgIsolationLncId) {
const bver = tv['coef_reduction_deperdition'].find(
(v) =>
zoneClimatique.toLowerCase().startsWith(v.zone_climatique?.toLowerCase()) &&
parseInt(v.enum_cfg_isolation_lnc_id) === parseInt(enumCfgIsolationLncId)
)?.b;
if (!bver) {
logger.error(
`Pas de valeur b pour zoneClimatique:${zoneClimatique}, enumCfgIsolationLncId:${enumCfgIsolationLncId}`
);
return;
}
return parseFloat(bver);
}
/**
* Calcul des coefficients de transparence des espaces tampons
*
* @param tvCoefTransparenceEtsId {number}
* @return {number|undefined}
*/
getCoefTransparenceEts(tvCoefTransparenceEtsId) {
const coefTransparence = tv['coef_transparence_ets'].find(
(v) => parseInt(v.tv_coef_transparence_ets_id) === parseInt(tvCoefTransparenceEtsId)
)?.coef_transparence_ets;
if (!coefTransparence) {
logger.error(
`Pas de valeur coef_transparence_ets pour tvCoefTransparenceEtsId:${tvCoefTransparenceEtsId}`
);
return;
}
return parseFloat(coefTransparence);
}
/**
* @see 18.5 - Coefficients d’orientation et d’inclinaison des parois vitrées : C1
*
* @param enumOrientationId {number}
* @param enumInclinaisonVitrageId {number}
* @param zoneClimatiqueId {number}
* @param mois {string}
*
* @return {number|undefined}
*/
getCoefficientBaieVitree(enumOrientationId, enumInclinaisonVitrageId, zoneClimatiqueId, mois) {
const orientation = enums.orientation[enumOrientationId];
const inclinaison = enums.inclinaison_vitrage[enumInclinaisonVitrageId];
const zoneClimatique = enums.zone_climatique[zoneClimatiqueId];
const c1ZoneClimatique = tv['c1'][zoneClimatique][mois];
if (inclinaison === 'horizontal') {
return c1ZoneClimatique[inclinaison];
}
return c1ZoneClimatique[`${orientation} ${inclinaison}`];
}
}