Skip to content

Commit

Permalink
Merge pull request #303 from RedFroggy/fix302Uw
Browse files Browse the repository at this point in the history
fix(fix-302): Uw is obtained by interpolation if Ug is not present in the value tables
  • Loading branch information
jgavignet authored Jan 16, 2025
2 parents 382ba7c + 893c66d commit 9c823e0
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/2021_04_13_qualite_isolation.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function calc_qualite_isolation(enveloppe, dp) {
} else {
if (
plancherHaut.donnee_entree.enum_type_plancher_haut_id === '12' ||
plancherHaut.donnee_entree.description.toLowerCase().indexOf('combles aménagés') !== -1
plancherHaut.donnee_entree.description?.toLowerCase().indexOf('combles aménagés') !== -1
) {
phCombleAmenagee.push(plancherHaut);
} else {
Expand Down
38 changes: 4 additions & 34 deletions src/3.2.2_plancher_bas.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import enums from './enums.js';
import b from './3.1_b.js';
import { tv, requestInput, getKeyByValue, bug_for_bug_compat } from './utils.js';
import { tv, requestInput, getKeyByValue, bug_for_bug_compat, getRange } from './utils.js';

const scriptName = new URL(import.meta.url).pathname.split('/').pop();

Expand Down Expand Up @@ -53,36 +53,6 @@ function tv_upb(di, de, du, pc_id, zc, effetJoule) {
}
}

function ue_ranges(inputNumber, ranges) {
const result = [];

if (inputNumber < ranges[0]) {
result.push(ranges[0]);
result.push(ranges[1]);
}
if (inputNumber > ranges[ranges.length - 1]) {
result.push(ranges[ranges.length - 2]);
result.push(ranges[ranges.length - 1]);
}
if (ranges.includes(inputNumber)) {
result.push(inputNumber);
result.push(inputNumber);
} else {
ranges.find((range, index) => {
if (inputNumber < range) {
if (index > 0) {
result.push(ranges[index - 1]);
} else {
result.push(ranges[index]);
}
result.push(ranges[index]);
return true;
}
});
}
return result;
}

const values_2s_p = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20];

function tv_ue(di, de, du, pc_id, pb_list) {
Expand All @@ -92,14 +62,14 @@ function tv_ue(di, de, du, pc_id, pb_list) {
if (type_adjacence === 'terre-plein') {
if (Number(pc_id) < 7) {
type_adjacence_plancher = 'terre plein bâtiment construit avant 2001';
[upb1, upb2] = ue_ranges(di.upb, [0.46, 0.59, 0.85, 1.5, 3.4]);
[upb1, upb2] = getRange(di.upb, [0.46, 0.59, 0.85, 1.5, 3.4]);
} else {
type_adjacence_plancher = 'terre plein bâtiment construit à partir de 2001';
[upb1, upb2] = ue_ranges(di.upb, [0.31, 0.37, 0.46, 0.6, 0.85, 1.5, 3.4]);
[upb1, upb2] = getRange(di.upb, [0.31, 0.37, 0.46, 0.6, 0.85, 1.5, 3.4]);
}
} else {
type_adjacence_plancher = 'plancher sur vide sanitaire ou sous-sol non chauffé';
[upb1, upb2] = ue_ranges(di.upb, [0.31, 0.34, 0.37, 0.41, 0.45, 0.83, 1.43, 3.33]);
[upb1, upb2] = getRange(di.upb, [0.31, 0.34, 0.37, 0.41, 0.45, 0.83, 1.43, 3.33]);
}

/**
Expand Down
86 changes: 68 additions & 18 deletions src/3.3_baie_vitree.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import b from './3.1_b.js';
import { tv, requestInput, requestInputID, bug_for_bug_compat } from './utils.js';
import { tv, requestInput, requestInputID, bug_for_bug_compat, getRange } from './utils.js';
import tvs from './tv.js';

function tv_ug(di, de, du) {
const matcher = {
Expand All @@ -22,24 +23,73 @@ function tv_ug(di, de, du) {
}
}

function tv_uw(di, de, du) {
const matcher = {
enum_type_baie_id: requestInputID(de, du, 'type_baie')
};
function tv_uw(di, de) {
const enum_type_baie_id = de.enum_type_baie_id;
const matcher = { enum_type_baie_id };
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 (matcher.enum_type_baie_id && ['1', '2', '3'].includes(enum_type_baie_id)) {
const row = tv('uw', matcher);
if (row) {
uw = Number(row.uw);
de.tv_uw_id = Number(row.tv_uw_id);
}
} else {
const enum_type_materiaux_menuiserie_id = de.enum_type_materiaux_menuiserie_id;
matcher.enum_type_materiaux_menuiserie_id = enum_type_materiaux_menuiserie_id;

// Récupération de toutes les valeurs de Ug présentes dans les tables Uw pour le type de baie et matériaux de la baie vitrée
const ugValues = tvs.uw
.filter((row) => {
return (
row.enum_type_baie_id.split('|').includes(enum_type_baie_id) &&
row.enum_type_materiaux_menuiserie_id
.split('|')
.includes(enum_type_materiaux_menuiserie_id)
);
})
.map((row) => parseFloat(row.ug));

/**
* 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.
*/
let ug1, ug2;
[ug1, ug2] = getRange(di.ug, ugValues);

const matcher_1 = { ...matcher, ...{ ug: `^${ug1}$` } };
const row_1 = tv('uw', matcher_1);
const delta_ug = ug2 - ug1;

if (delta_ug === 0) {
if (row_1) {
uw = Number(row_1.uw);
}
} else {
const matcher_2 = { ...matcher, ...{ ug: `^${ug2}$` } };
const row_2 = tv('uw', matcher_2);

if (
matcher.enum_type_baie_id &&
!['1', '2', '3'].includes(matcher.enum_type_baie_id.toString())
) {
matcher.enum_type_materiaux_menuiserie_id = requestInputID(de, du, 'type_materiaux_menuiserie');
matcher.ug = `^${di.ug}$`;
if (row_1 && row_2) {
const delta_uw = Number(row_2.uw) - Number(row_1.uw);
uw = Number(row_1.uw) + (delta_uw * (di.ug - ug1)) / delta_ug;
}
}
}
const row = tv('uw', matcher);
if (row) {
di.uw = Number(row.uw);
de.tv_uw_id = Number(row.tv_uw_id);

if (uw) {
di.uw = uw;
} else {
console.error('!! pas de valeur forfaitaire trouvée pour uw !!');
console.error(`
Pas de valeur forfaitaire uw trouvée pour la baie vitrée ${de.description}.
`);
}
}

Expand Down Expand Up @@ -158,7 +208,7 @@ export default function calc_bv(bv, zc) {

tv_ug(di, de, du);
if (de.uw_saisi) di.uw = de.uw_saisi;
else tv_uw(di, de, du);
else tv_uw(di, de);

/**
* S'il existe une double-fenêtre, calcul des facteurs sw et uw équivalents
Expand Down Expand Up @@ -196,7 +246,7 @@ export default function calc_bv(bv, zc) {
if (deDoubleFenetre.uw_saisi) {
diDoubleFenetre.uw = deDoubleFenetre.uw_saisi;
} else {
tv_uw(diDoubleFenetre, deDoubleFenetre, du);
tv_uw(diDoubleFenetre, deDoubleFenetre);
}

const uw = 1 / (1 / di.uw + 1 / diDoubleFenetre.uw + 0.07);
Expand Down
40 changes: 21 additions & 19 deletions src/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,29 +285,31 @@ export function calcul_3cl(dpe) {
* dans tous les DPEs (parfois 0 = 'Oui', d'autres 0 = 'Non')
*/
ecs.generateur_ecs_collection.generateur_ecs.forEach((generateur) => {
const ficheProductionVolumeHabitable = getFicheTechnique(
dpe,
'8',
'hors volume habitable',
[generateur.donnee_entree.description]
);

if (ficheProductionVolumeHabitable) {
const pvcFicheTechnique = containsAnySubstring(ficheProductionVolumeHabitable.valeur, [
if (generateur.donnee_entree.description) {
const ficheProductionVolumeHabitable = getFicheTechnique(
dpe,
'8',
'hors volume habitable',
'oui'
])
? 0
: 1;

if (generateur.donnee_entree.position_volume_chauffe !== pvcFicheTechnique) {
console.error(
`La valeur de la variable position_volume_chauffe pour le générateur ECS ${generateur.donnee_entree.description}
[generateur.donnee_entree.description]
);

if (ficheProductionVolumeHabitable) {
const pvcFicheTechnique = containsAnySubstring(ficheProductionVolumeHabitable.valeur, [
'hors volume habitable',
'oui'
])
? 0
: 1;

if (generateur.donnee_entree.position_volume_chauffe !== pvcFicheTechnique) {
console.error(
`La valeur de la variable position_volume_chauffe pour le générateur ECS ${generateur.donnee_entree.description}
ne correspond pas à celle présente dans la fiche technique "${ficheProductionVolumeHabitable.description}".
La valeur de la fiche technique est prise en compte.`
);
);

generateur.donnee_entree.position_volume_chauffe = pvcFicheTechnique;
generateur.donnee_entree.position_volume_chauffe = pvcFicheTechnique;
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/ficheTechnique.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export default function getFicheTechnique(
fichesTechniques = [fichesTechniques];
}

classifications = classifications.filter((classification) => classification);

fichesTechniques = fichesTechniques
.filter((ficheTechnique) => ficheTechnique)
.reduce((acc, ficheTechnique) => {
Expand Down
45 changes: 44 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,9 @@ export function isEffetJoule(instal_ch) {
* @returns {boolean}
*/
export function containsAnySubstring(mainString, substrings) {
return substrings.some((substring) => mainString.toLowerCase().includes(substring.toLowerCase()));
return substrings.some((substring) =>
mainString.toString().toLowerCase().includes(substring.toLowerCase())
);
}

/**
Expand All @@ -455,3 +457,44 @@ export function convertExpression(expression) {
);
return expression;
}

/**
* Retourne les valeurs qui encadrent inputNumber dans ranges
* Si inputNumber est présent dans ranges, inputNumber est retourné comme borne 1 et borne 2
*
* @param inputNumber {float}
* @param ranges {number[]}
* @returns {*[]}
*/
export function getRange(inputNumber, ranges) {
const result = [];

ranges.sort();

if (inputNumber < ranges[0]) {
result.push(ranges[0]);
result.push(ranges[1]);
return result;
}
if (inputNumber > ranges[ranges.length - 1]) {
result.push(ranges[ranges.length - 2]);
result.push(ranges[ranges.length - 1]);
}
if (ranges.includes(inputNumber)) {
result.push(inputNumber);
result.push(inputNumber);
} else {
ranges.find((range, index) => {
if (inputNumber < range) {
if (index > 0) {
result.push(ranges[index - 1]);
} else {
result.push(ranges[index]);
}
result.push(ranges[index]);
return true;
}
});
}
return result;
}
11 changes: 10 additions & 1 deletion src/utils.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { convertExpression, getThicknessFromDescription } from './utils.js';
import { convertExpression, getRange, getThicknessFromDescription } from './utils.js';

describe('Utils unit tests', () => {
it.each([
Expand All @@ -24,4 +24,13 @@ describe('Utils unit tests', () => {
])('should transform expression %s to %s', (expression, expected) => {
expect(convertExpression(expression)).toBe(expected);
});

it.each([
[[1, 1.2, 3.4, 5.6], 0.5, [1, 1.2]],
[[1, 1.2, 3.4, 5.6], 1, [1, 1]],
[[1, 1.2, 3.4, 5.6], 1.3, [1.2, 3.4]],
[[1, 1.2, 3.4, 5.6], 6.5, [3.4, 5.6]]
])('should for values %s and inputNumber %s return range %s', (ranges, inputNumber, expected) => {
expect(getRange(inputNumber, ranges)).toStrictEqual(expected);
});
});

0 comments on commit 9c823e0

Please sign in to comment.