Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/features/dpe/domain/models/dpe.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,15 @@ export interface Logement {
installation_ecs_collection: { installation_ecs: InstallationEcs[] };
installation_chauffage_collection: { installation_chauffage: InstallationChauffage[] };
sortie: Sortie;
donnees_de_calcul: LogementDonneesCalcul;
}

export interface LogementDonneesCalcul {
apportsInterneCh: { [key: string]: number };
apportsInterneDepensier: { [key: string]: number };
apportsSolaire: { [key: string]: number };
besoinChauffageHP: { [key: string]: number };
besoinChauffageDepensierHP: { [key: string]: number };
}

export interface Tertiaire extends Logement {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export interface GenerateurChauffageDE extends DE {
enum_type_generateur_ch_id: number;
enum_usage_generateur_id: number;
enum_type_energie_id: number;
position_volume_chauffe: boolean;
position_volume_chauffe: number;
tv_rendement_generation_id?: number;
tv_scop_id?: number;
tv_temp_fonc_100_id?: number;
Expand All @@ -81,7 +81,7 @@ export interface GenerateurChauffageDE extends DE {
identifiant_reseau_chaleur?: string;
date_arrete_reseau_chaleur?: string;
priorite_generateur_cascade?: number;
presence_ventouse?: boolean;
presence_ventouse?: number;
presence_regulation_combustion?: boolean;
enum_methode_saisie_carac_sys_id: number;
enum_lien_generateur_emetteur_id: number;
Expand Down
6 changes: 4 additions & 2 deletions src/features/dpe/infrastructure/froid/frTv.store.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ export class FrTvStore extends TvStore {
* — e_fr_28 : ensoleillement reçu en période de refroidissement pour un mois donné et une consigne de refroidissement à 28°C (comportement conventionnel).
* — textmoy_clim_26 : Température extérieure moyenne pour un mois donné et une consigne de refroidissement à 26°C (comportement conventionnel).
* — textmoy_clim_28 : nombre d’heures de chauffage pour un mois donné et une consigne de refroidissement à 28°C (comportement conventionnel).
* — dh19 : degrés heures de chauffage pour un mois donné à 19°C (comportement conventionnel).
* — dh21 : degrés heures de chauffage pour un mois donné à 21°C (comportement dépensier).
*
* @param type {'e', nref26' | 'nref28' | 'e_fr_26' | 'e_fr_28' | 'textmoy_clim_26' | 'textmoy_clim_28'}
* @param type {'e', nref26' | 'nref28' | 'e_fr_26' | 'e_fr_28' | 'textmoy_clim_26' | 'textmoy_clim_28'| 'dh19'| 'dh21'}
* @param classeAltitude {string}
* @param zoneClimatique {string}
* @param mois {string}
Expand All @@ -31,6 +33,6 @@ export class FrTvStore extends TvStore {
values = values[ilpa];
}

return values[classeAltitude][mois][zoneClimatique];
return parseFloat(values[classeAltitude][mois][zoneClimatique]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { BesoinFroidService } from './froid/besoin-froid.service.js';
import { ApportGratuitService } from './apport_gratuit/apport-gratuit.service.js';
import { InstallationEcsService } from '../ecs/installation-ecs.service.js';
import { PerteEcsRecupService } from './ecs/perte-ecs-recup.service.js';
import { BesoinChService } from './ch/besoin-ch.service.js';
import { PerteChRecupService } from './ch/perte-ch-recup.service.js';

/**
* Calcul des déperditions de l’enveloppe GV
Expand All @@ -21,6 +23,11 @@ export class ApportEtBesoinService {
*/
#besoinEcsService;

/**
* @type {BesoinChService}
*/
#besoinChService;

/**
* @type {InstallationEcsService}
*/
Expand All @@ -36,32 +43,43 @@ export class ApportEtBesoinService {
*/
#besoinFroidService;

/**
* @type {PerteChRecupService}
*/
#perteChRecupService;

/**
* @type {ApportGratuitService}
*/
#apportGratuitService;

/**
* @param besoinEcsService {BesoinEcsService}
* @param besoinChService {BesoinChService}
* @param installationEcsService {InstallationEcsService}
* @param perteEcsRecupService {PerteEcsRecupService}
* @param besoinFroidService {BesoinFroidService}
* @param surfaceSudEquivalenteService {SurfaceSudEquivalenteService}
* @param perteChRecupService {PerteChRecupService}
* @param apportGratuitService {ApportGratuitService}
*/
constructor(
besoinEcsService = inject(BesoinEcsService),
besoinChService = inject(BesoinChService),
installationEcsService = inject(InstallationEcsService),
perteEcsRecupService = inject(PerteEcsRecupService),
besoinFroidService = inject(BesoinFroidService),
surfaceSudEquivalenteService = inject(SurfaceSudEquivalenteService),
perteChRecupService = inject(PerteChRecupService),
apportGratuitService = inject(ApportGratuitService)
) {
this.#besoinEcsService = besoinEcsService;
this.#besoinChService = besoinChService;
this.#installationEcsService = installationEcsService;
this.#perteEcsRecupService = perteEcsRecupService;
this.#besoinFroidService = besoinFroidService;
this.#surfaceSudEquivalenteService = surfaceSudEquivalenteService;
this.#perteChRecupService = perteChRecupService;
this.#apportGratuitService = apportGratuitService;
}

Expand All @@ -80,6 +98,26 @@ export class ApportEtBesoinService {
*/
this.#installationEcsService.execute(ctx, logement, besoinEcs);

const apportsInternes = this.#apportGratuitService.apportInterne(ctx, logement);
const apportsSolaires = this.#apportGratuitService.apportSolaire(ctx, logement);

const pertesEcsRecup = this.#perteEcsRecupService.execute(ctx, logement);
// Besoin de chauffage hors pertes récupérées
const besoinChHP = this.#besoinChService.execute(ctx, logement);
const pertesChauffageRecup = this.#perteChRecupService.execute(ctx, logement);

const besoinCh = {
besoin_ch: besoinChHP.besoin_ch_hp,
besoin_ch_depensier: besoinChHP.besoin_ch_depensier_hp
};
besoinCh.besoin_ch -= pertesEcsRecup.pertes_distribution_ecs_recup;
besoinCh.besoin_ch -= pertesEcsRecup.pertes_stockage_ecs_recup;
besoinCh.besoin_ch -= pertesChauffageRecup.pertes_generateur_ch_recup;

besoinCh.besoin_ch_depensier -= pertesEcsRecup.pertes_distribution_ecs_recup_depensier;
besoinCh.besoin_ch_depensier -= pertesEcsRecup.pertes_stockage_ecs_recup_depensier;
besoinCh.besoin_ch_depensier -= pertesChauffageRecup.pertes_generateur_ch_recup_depensier;

return {
...besoinEcs,
...{
Expand All @@ -92,9 +130,11 @@ export class ApportEtBesoinService {
v40_ecs_journalier_depensier: ctx.nadeq * 79
},
...this.#besoinFroidService.execute(ctx, logement),
...this.#apportGratuitService.apportInterne(ctx, logement),
...this.#apportGratuitService.apportSolaire(ctx, logement),
...this.#perteEcsRecupService.execute(ctx, logement)
...apportsInternes,
...apportsSolaires,
...pertesEcsRecup,
...pertesChauffageRecup,
...besoinCh
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import { BesoinFroidService } from './froid/besoin-froid.service.js';
import { ApportGratuitService } from './apport_gratuit/apport-gratuit.service.js';
import { PerteEcsRecupService } from './ecs/perte-ecs-recup.service.js';
import { InstallationEcsService } from '../ecs/installation-ecs.service.js';
import { PerteChRecupService } from './ch/perte-ch-recup.service.js';
import { BesoinChService } from './ch/besoin-ch.service.js';
import corpus from '../../../../../test/corpus-sano.json';
import { getAdemeFileJson } from '../../../../../test/test-helpers.js';
import { PRECISION_PERCENT } from '../../../../../test/constant.js';
import { DpeNormalizerService } from '../../../normalizer/domain/dpe-normalizer.service.js';
import { ContexteBuilder } from '../contexte.builder.js';

/** @type {SurfaceSudEquivalenteService} **/
let surfaceSudEquivalenteService;
Expand All @@ -26,6 +33,18 @@ let perteEcsRecupService;
/** @type {ApportGratuitService} **/
let apportGratuitService;

/** @type {PerteChRecupService} **/
let perteChRecupService;

/** @type {BesoinChService} **/
let besoinChService;

/** @type {DpeNormalizerService} **/
let normalizerService;

/** @type {ContexteBuilder} **/
let contexteBuilder;

/** @type {ApportEtBesoinService} **/
let service;

Expand All @@ -37,18 +56,24 @@ describe('Calcul des apports et besoin du logement', () => {
tvStore = new BaieVitreeTvStore();
surfaceSudEquivalenteService = new SurfaceSudEquivalenteService(tvStore);
besoinEcsService = new BesoinEcsService();
besoinChService = new BesoinChService();
besoinFroidService = new BesoinFroidService();
installationEcsService = new InstallationEcsService();
perteEcsRecupService = new PerteEcsRecupService();
apportGratuitService = new ApportGratuitService();
perteChRecupService = new PerteChRecupService();
service = new ApportEtBesoinService(
besoinEcsService,
besoinChService,
installationEcsService,
perteEcsRecupService,
besoinFroidService,
surfaceSudEquivalenteService,
perteChRecupService,
apportGratuitService
);
normalizerService = new DpeNormalizerService();
contexteBuilder = new ContexteBuilder();
});

test('Determination des apports et besoin du logement', () => {
Expand All @@ -57,6 +82,10 @@ describe('Calcul des apports et besoin du logement', () => {
besoin_ecs: 1526,
besoin_ecs_depensier: 2685.3
});
vi.spyOn(besoinChService, 'execute').mockReturnValue({
besoin_ch_hp: 2563,
besoin_ch_depensier_hp: 3258.6
});
vi.spyOn(besoinFroidService, 'execute').mockReturnValue({
besoin_fr: 896,
besoin_fr_depensier: 1025.3
Expand All @@ -73,7 +102,12 @@ describe('Calcul des apports et besoin du logement', () => {
vi.spyOn(perteEcsRecupService, 'execute').mockReturnValue({
pertes_distribution_ecs_recup: 354.2,
pertes_distribution_ecs_recup_depensier: 532.6,
pertes_stockage_ecs_recup: 25.9
pertes_stockage_ecs_recup: 25.9,
pertes_stockage_ecs_recup_depensier: 12.9
});
vi.spyOn(perteChRecupService, 'execute').mockReturnValue({
pertes_generateur_ch_recup: 102.2,
pertes_generateur_ch_recup_depensier: 153.4
});

/** @type {Contexte} */
Expand All @@ -84,6 +118,8 @@ describe('Calcul des apports et besoin du logement', () => {
surface_sud_equivalente: 18.5,
besoin_ecs: 1526,
besoin_ecs_depensier: 2685.3,
besoin_ch: 2080.7000000000003,
besoin_ch_depensier: 2559.7,
besoin_fr: 896,
besoin_fr_depensier: 1025.3,
apport_solaire_ch: 5236.9,
Expand All @@ -95,12 +131,77 @@ describe('Calcul des apports et besoin du logement', () => {
v40_ecs_journalier_depensier: 197.5,
pertes_distribution_ecs_recup: 354.2,
pertes_distribution_ecs_recup_depensier: 532.6,
pertes_stockage_ecs_recup: 25.9
pertes_generateur_ch_recup: 102.2,
pertes_generateur_ch_recup_depensier: 153.4,
pertes_stockage_ecs_recup: 25.9,
pertes_stockage_ecs_recup_depensier: 12.9
});
expect(surfaceSudEquivalenteService.execute).toHaveBeenCalledWith(ctx, logement.enveloppe);
expect(besoinEcsService.execute).toHaveBeenCalledWith(ctx);
expect(besoinFroidService.execute).toHaveBeenCalledWith(ctx, logement);
expect(apportGratuitService.apportSolaire).toHaveBeenCalledWith(ctx, logement);
expect(apportGratuitService.apportInterne).toHaveBeenCalledWith(ctx, logement);
});

describe("Test d'intégration pour les besoins en chauffage", () => {
test.each(corpus)(
'Vérification de la DI besoin_ch des besoins en chauffage pour dpe %s',
(ademeId) => {
/**
* @type {Dpe}
*/
let dpeRequest = getAdemeFileJson(ademeId);
dpeRequest = normalizerService.normalize(dpeRequest);

dpeRequest.logement.donnees_de_calcul = {
apportsInterneDepensier: [],
apportsInterneCh: [],
apportsSolaire: [],
besoinChauffageHP: [],
besoinChauffageDepensierHP: []
};

/** @type {Contexte} */
const ctx = contexteBuilder.fromDpe(dpeRequest);
const apportEtBesoin = service.execute(ctx, dpeRequest.logement);

expect(
Math.abs(
apportEtBesoin.besoin_ch - dpeRequest.logement.sortie.apport_et_besoin.besoin_ch
) / (dpeRequest.logement.sortie.apport_et_besoin.besoin_ch || 1)
).toBeLessThan(PRECISION_PERCENT);
}
);

test.each(corpus)(
'Vérification de la DI besoin_ch_depensier des besoins en chauffage pour dpe %s',
(ademeId) => {
/**
* @type {Dpe}
*/
let dpeRequest = getAdemeFileJson(ademeId);
dpeRequest = normalizerService.normalize(dpeRequest);

dpeRequest.logement.donnees_de_calcul = {
apportsInterneDepensier: [],
apportsInterneCh: [],
apportsSolaire: [],
besoinChauffageHP: [],
besoinChauffageDepensierHP: []
};

/** @type {Contexte} */
const ctx = contexteBuilder.fromDpe(dpeRequest);

const apportEtBesoin = service.execute(ctx, dpeRequest.logement);

expect(
Math.abs(
apportEtBesoin.besoin_ch_depensier -
dpeRequest.logement.sortie.apport_et_besoin.besoin_ch_depensier
) / (dpeRequest.logement.sortie.apport_et_besoin.besoin_ch_depensier || 1)
).toBeLessThan(PRECISION_PERCENT);
}
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class ApportGratuitService {

return mois_liste.reduce(
(acc, mois) => {
acc.apport_solaire_ch += this.apportSolaireMois(
const apportSolaire = this.apportSolaireMois(
ctx,
logement.enveloppe,
mois,
Expand All @@ -58,6 +58,9 @@ export class ApportGratuitService {
ctx.inertie.ilpa
)
);
acc.apport_solaire_ch += apportSolaire;
logement.donnees_de_calcul.apportsSolaire[mois] = apportSolaire;

if (clim.length > 0) {
acc.apport_solaire_fr += this.apportSolaireMois(
ctx,
Expand All @@ -84,7 +87,7 @@ export class ApportGratuitService {

return mois_liste.reduce(
(acc, mois) => {
acc.apport_interne_ch += this.apportInterneMois(
const apportInterne = this.apportInterneMois(
ctx,
this.#frTvStore.getData(
'nref19',
Expand All @@ -94,6 +97,19 @@ export class ApportGratuitService {
ctx.inertie.ilpa
)
);
acc.apport_interne_ch += apportInterne;
logement.donnees_de_calcul.apportsInterneCh[mois] = apportInterne;
logement.donnees_de_calcul.apportsInterneDepensier[mois] = this.apportInterneMois(
ctx,
this.#frTvStore.getData(
'nref21',
ctx.altitude.value,
ctx.zoneClimatique.value,
mois,
ctx.inertie.ilpa
)
);

if (clim.length > 0) {
acc.apport_interne_fr += this.apportInterneMois(
ctx,
Expand Down
Loading
Loading