@open3cl/engine 1.0.10 → 1.0.12
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.
- package/features/dpe/domain/models/installation-ecs.model.ts +15 -2
- package/features/dpe/domain/models/type-habitation.model.js +1 -0
- package/features/dpe/domain/models/type-stockage.model.js +8 -0
- package/features/dpe/infrastructure/ecs/ecsTv.store.js +65 -0
- package/features/dpe/infrastructure/ecs/ecsTv.store.spec.js +69 -0
- package/features/dpe/infrastructure/{baieVitreeTv.store.js → enveloppe/baieVitreeTv.store.js} +5 -5
- package/features/dpe/infrastructure/{pontThermiqueTv.store.js → enveloppe/pontThermiqueTv.store.js} +3 -3
- package/features/dpe/infrastructure/froid/frTv.store.js +36 -0
- package/features/dpe/infrastructure/froid/frTv.store.spec.js +52 -0
- package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.js +100 -0
- package/features/engine/domain/apport_et_besoin/apport-et-besoin.service.spec.js +106 -0
- package/features/engine/domain/apport_et_besoin/apport_gratuit/apport-gratuit.service.js +134 -0
- package/features/engine/domain/apport_et_besoin/apport_gratuit/apport-gratuit.service.spec.js +167 -0
- package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.js +58 -0
- package/features/engine/domain/apport_et_besoin/ecs/besoin-ecs.service.spec.js +67 -0
- package/features/engine/domain/apport_et_besoin/ecs/perte-ecs-recup.service.js +123 -0
- package/features/engine/domain/apport_et_besoin/ecs/perte-ecs-recup.service.spec.js +205 -0
- package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.js +131 -0
- package/features/engine/domain/apport_et_besoin/froid/besoin-froid.service.spec.js +229 -0
- package/features/engine/domain/{logement → apport_et_besoin}/surface-sud-equivalente.service.js +9 -10
- package/features/engine/domain/{logement → apport_et_besoin}/surface-sud-equivalente.service.spec.js +63 -43
- package/features/engine/domain/contexte.builder.js +53 -6
- package/features/engine/domain/contexte.builder.spec.js +59 -3
- package/features/engine/domain/ecs/generateur-ecs.service.js +106 -0
- package/features/engine/domain/ecs/generateur-ecs.service.spec.js +136 -0
- package/features/engine/domain/ecs/installation-ecs.service.js +156 -0
- package/features/engine/domain/ecs/installation-ecs.service.spec.js +284 -0
- package/features/engine/domain/engine.service.js +10 -13
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.js +1 -1
- package/features/engine/domain/enveloppe/baie_vitree/deperdition-baie-vitree.service.spec.js +1 -1
- package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.js +1 -1
- package/features/engine/domain/enveloppe/espace_tampon/espace-tampon.service.spec.js +1 -1
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.js +1 -1
- package/features/engine/domain/enveloppe/pont_thermique/deperdition-pont-thermique.service.spec.js +1 -1
- package/features/engine/domain/logement/nadeq.service.js +8 -7
- package/features/engine/domain/logement/nadeq.service.spec.js +6 -16
- package/features/engine/domain/models/contexte.model.ts +9 -0
- package/package.json +1 -1
- /package/features/dpe/infrastructure/{baieVitreeTv.store.spec.js → enveloppe/baieVitreeTv.store.spec.js} +0 -0
- /package/features/dpe/infrastructure/{pontThermiqueTv.store.spec.js → enveloppe/pontThermiqueTv.store.spec.js} +0 -0
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { ContexteBuilder } from './contexte.builder.js';
|
|
2
|
-
import { beforeEach, describe, expect, test } from 'vitest';
|
|
2
|
+
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
3
3
|
import { TypeDpe, TypeHabitation } from '../../dpe/domain/models/type-habitation.model.js';
|
|
4
|
+
import { NadeqService } from './logement/nadeq.service.js';
|
|
5
|
+
|
|
6
|
+
/** @type {NadeqService} **/
|
|
7
|
+
let nadeqService;
|
|
4
8
|
|
|
5
9
|
/** @type {ContexteBuilder} **/
|
|
6
10
|
let contexteBuilder;
|
|
7
11
|
|
|
8
12
|
describe('Generateur du contexte du calcul', () => {
|
|
9
13
|
beforeEach(() => {
|
|
10
|
-
|
|
14
|
+
nadeqService = new NadeqService();
|
|
15
|
+
contexteBuilder = new ContexteBuilder(nadeqService);
|
|
11
16
|
});
|
|
12
17
|
|
|
13
18
|
test('Contexte avec effet joule', () => {
|
|
@@ -79,11 +84,26 @@ describe('Generateur du contexte du calcul', () => {
|
|
|
79
84
|
});
|
|
80
85
|
});
|
|
81
86
|
|
|
87
|
+
test('Contexte avec calcul du nadeq', () => {
|
|
88
|
+
vi.spyOn(nadeqService, 'execute').mockReturnValue(1.58);
|
|
89
|
+
const dpe = {
|
|
90
|
+
logement: {
|
|
91
|
+
caracteristique_generale: {},
|
|
92
|
+
installation_chauffage_collection: {}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
|
|
97
|
+
nadeq: 1.58
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
82
101
|
test('Récupération des informations du logement concerné par le DPE', () => {
|
|
83
102
|
let dpe = {
|
|
84
103
|
logement: {
|
|
85
104
|
meteo: {
|
|
86
|
-
enum_zone_climatique_id: 1
|
|
105
|
+
enum_zone_climatique_id: 1,
|
|
106
|
+
enum_classe_altitude_id: 2
|
|
87
107
|
},
|
|
88
108
|
caracteristique_generale: {
|
|
89
109
|
enum_periode_construction_id: 4,
|
|
@@ -106,11 +126,16 @@ describe('Generateur du contexte du calcul', () => {
|
|
|
106
126
|
zoneClimatique: {
|
|
107
127
|
id: '1',
|
|
108
128
|
value: 'h1a'
|
|
129
|
+
},
|
|
130
|
+
altitude: {
|
|
131
|
+
id: '2',
|
|
132
|
+
value: '400-800m'
|
|
109
133
|
}
|
|
110
134
|
});
|
|
111
135
|
|
|
112
136
|
dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = '5';
|
|
113
137
|
dpe.logement.meteo.enum_zone_climatique_id = '4';
|
|
138
|
+
dpe.logement.meteo.enum_classe_altitude_id = '3';
|
|
114
139
|
expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
|
|
115
140
|
surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_logement,
|
|
116
141
|
typeHabitation: TypeHabitation.APPARTEMENT,
|
|
@@ -118,6 +143,10 @@ describe('Generateur du contexte du calcul', () => {
|
|
|
118
143
|
zoneClimatique: {
|
|
119
144
|
id: '4',
|
|
120
145
|
value: 'h2a'
|
|
146
|
+
},
|
|
147
|
+
altitude: {
|
|
148
|
+
id: '3',
|
|
149
|
+
value: 'supérieur à 800m'
|
|
121
150
|
}
|
|
122
151
|
});
|
|
123
152
|
|
|
@@ -128,4 +157,31 @@ describe('Generateur du contexte du calcul', () => {
|
|
|
128
157
|
typeDpe: TypeDpe.IMMEUBLE
|
|
129
158
|
});
|
|
130
159
|
});
|
|
160
|
+
|
|
161
|
+
test('Contexte avec calcul ilpa', () => {
|
|
162
|
+
const dpe = {
|
|
163
|
+
logement: {
|
|
164
|
+
caracteristique_generale: {},
|
|
165
|
+
meteo: {
|
|
166
|
+
batiment_materiaux_anciens: 0
|
|
167
|
+
},
|
|
168
|
+
enveloppe: {
|
|
169
|
+
inertie: {
|
|
170
|
+
enum_classe_inertie_id: 4
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
expect(contexteBuilder.fromDpe(dpe)).toMatchObject({ inertie: { id: 4, ilpa: 0 } });
|
|
177
|
+
|
|
178
|
+
dpe.logement.enveloppe.inertie.enum_classe_inertie_id = 1;
|
|
179
|
+
expect(contexteBuilder.fromDpe(dpe)).toMatchObject({ inertie: { id: 1, ilpa: 0 } });
|
|
180
|
+
|
|
181
|
+
dpe.logement.meteo.batiment_materiaux_anciens = 1;
|
|
182
|
+
expect(contexteBuilder.fromDpe(dpe)).toMatchObject({ inertie: { id: 1, ilpa: 1 } });
|
|
183
|
+
|
|
184
|
+
dpe.logement.enveloppe.inertie.enum_classe_inertie_id = 2;
|
|
185
|
+
expect(contexteBuilder.fromDpe(dpe)).toMatchObject({ inertie: { id: 2, ilpa: 1 } });
|
|
186
|
+
});
|
|
131
187
|
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { TypeStockage } from '../../../dpe/domain/models/type-stockage.model.js';
|
|
2
|
+
import { inject } from 'dioma';
|
|
3
|
+
import { EcsTvStore } from '../../../dpe/infrastructure/ecs/ecsTv.store.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Calcul des données de calcul pour chacun des générateurs
|
|
7
|
+
* Données calculées
|
|
8
|
+
* — Qgw : pertes liées au stockage de l'ECS pour chaque générateur
|
|
9
|
+
*/
|
|
10
|
+
export class GenerateurEcsService {
|
|
11
|
+
/**
|
|
12
|
+
* @type {EcsTvStore}
|
|
13
|
+
*/
|
|
14
|
+
#tvStore;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param tvStore {EcsTvStore}
|
|
18
|
+
*/
|
|
19
|
+
constructor(tvStore = inject(EcsTvStore)) {
|
|
20
|
+
this.#tvStore = tvStore;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Détermination des apports et besoins pour le bien concerné
|
|
25
|
+
*
|
|
26
|
+
* @param installationEcs {InstallationEcs}
|
|
27
|
+
*/
|
|
28
|
+
execute(installationEcs) {
|
|
29
|
+
const generateursEcs = installationEcs.generateur_ecs_collection.generateur_ecs || [];
|
|
30
|
+
|
|
31
|
+
generateursEcs.forEach((generateurEcs) => {
|
|
32
|
+
/** @type {GenerateurEcsDE}*/
|
|
33
|
+
const generateurEcsDE = generateurEcs.donnee_entree;
|
|
34
|
+
|
|
35
|
+
generateurEcs.donnee_utilisateur = {
|
|
36
|
+
Qgw: this.pertesStockage(generateurEcsDE)
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Pertes de stockage d'un générateur ECS.
|
|
43
|
+
* Seules les générateurs avec stockage indépendant et dissocié du générateur sont concernés
|
|
44
|
+
*
|
|
45
|
+
* 11.6.1 - Pertes de stockage des ballons d’accumulation
|
|
46
|
+
* 11.6.2 - Pertes des ballons électriques
|
|
47
|
+
*
|
|
48
|
+
* @param generateurEcsDE {GenerateurEcsDE}
|
|
49
|
+
* @return {number}
|
|
50
|
+
*/
|
|
51
|
+
pertesStockage(generateurEcsDE) {
|
|
52
|
+
const electrique = this.generateurElectrique(generateurEcsDE);
|
|
53
|
+
const typeStockage = this.typeStockage(generateurEcsDE);
|
|
54
|
+
|
|
55
|
+
if (typeStockage === TypeStockage.INSTANTANE) {
|
|
56
|
+
return 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let Qgw;
|
|
60
|
+
let volumeStockage = generateurEcsDE.volume_stockage;
|
|
61
|
+
|
|
62
|
+
if (electrique) {
|
|
63
|
+
const cr = this.#tvStore.getPertesStockage(
|
|
64
|
+
generateurEcsDE.enum_type_generateur_ecs_id,
|
|
65
|
+
volumeStockage
|
|
66
|
+
);
|
|
67
|
+
// Les pertes de stockage des ballons électriques (Wh)
|
|
68
|
+
Qgw = ((8592 * 45) / 24) * volumeStockage * cr;
|
|
69
|
+
} else {
|
|
70
|
+
// La présence d’un ballon de préparation de l’ECS est responsable de pertes de stockage Qgw (Wh)
|
|
71
|
+
Qgw = 67662 * volumeStockage ** 0.55;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return Qgw;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Return true si le générateur ECS est électrique
|
|
79
|
+
*
|
|
80
|
+
* 1 - abscence de stockage d'ecs (production instantanée)
|
|
81
|
+
* 2 - stockage indépendant de la production
|
|
82
|
+
* 3 - stockage intégré à la production
|
|
83
|
+
*
|
|
84
|
+
* @param generateurEcsDE {GenerateurEcsDE}
|
|
85
|
+
* @return {boolean}
|
|
86
|
+
*/
|
|
87
|
+
generateurElectrique(generateurEcsDE) {
|
|
88
|
+
return this.#tvStore
|
|
89
|
+
.getElectriqueEcsGenerateurs()
|
|
90
|
+
.includes(parseInt(generateurEcsDE.enum_type_generateur_ecs_id));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Return le type de stockage d'ECS
|
|
95
|
+
*
|
|
96
|
+
* @param generateurEcsDE {GenerateurEcsDE}
|
|
97
|
+
* @return TypeStockage
|
|
98
|
+
*/
|
|
99
|
+
typeStockage(generateurEcsDE) {
|
|
100
|
+
return parseInt(generateurEcsDE.enum_type_stockage_ecs_id) === 1
|
|
101
|
+
? TypeStockage.INSTANTANE
|
|
102
|
+
: parseInt(generateurEcsDE.enum_type_stockage_ecs_id) === 2
|
|
103
|
+
? TypeStockage.INDEPENDANT
|
|
104
|
+
: TypeStockage.INTEGRE;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
+
import { GenerateurEcsService } from './generateur-ecs.service.js';
|
|
3
|
+
import { EcsTvStore } from '../../../dpe/infrastructure/ecs/ecsTv.store.js';
|
|
4
|
+
import { TypeStockage } from '../../../dpe/domain/models/type-stockage.model.js';
|
|
5
|
+
|
|
6
|
+
/** @type {GenerateurEcsService} **/
|
|
7
|
+
let service;
|
|
8
|
+
|
|
9
|
+
/** @type {EcsTvStore} **/
|
|
10
|
+
let tvStore;
|
|
11
|
+
|
|
12
|
+
describe('Calcul des informations techniques des générateurs ECS', () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
tvStore = new EcsTvStore();
|
|
15
|
+
service = new GenerateurEcsService(tvStore);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe("Calcul des pertes de stockage d'un générateur", () => {
|
|
19
|
+
test.each([
|
|
20
|
+
{
|
|
21
|
+
label: 'Générateur ECS avec production instantanée',
|
|
22
|
+
enumTypeGenerateurEcsId: 1,
|
|
23
|
+
enumTypeStockageEcsId: 1,
|
|
24
|
+
volumeStockage: 100,
|
|
25
|
+
expected: 0
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: 'Générateur ECS avec stockage intégré au générateur',
|
|
29
|
+
enumTypeGenerateurEcsId: 1,
|
|
30
|
+
enumTypeStockageEcsId: 2,
|
|
31
|
+
volumeStockage: 100,
|
|
32
|
+
expected: 851814.11
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
label: 'Générateur ECS électrique avec stockage indépendant de 100L',
|
|
36
|
+
enumTypeGenerateurEcsId: 2,
|
|
37
|
+
enumTypeStockageEcsId: 3,
|
|
38
|
+
electrique: true,
|
|
39
|
+
volumeStockage: 250,
|
|
40
|
+
expected: 1288800
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
label: 'Générateur ECS à gaz avec stockage indépendant de 200L',
|
|
44
|
+
enumTypeGenerateurEcsId: 1,
|
|
45
|
+
enumTypeStockageEcsId: 3,
|
|
46
|
+
volumeStockage: 200,
|
|
47
|
+
expected: 1247128.86
|
|
48
|
+
}
|
|
49
|
+
])(
|
|
50
|
+
'$label',
|
|
51
|
+
({
|
|
52
|
+
enumTypeGenerateurEcsId,
|
|
53
|
+
volumeStockage,
|
|
54
|
+
enumTypeStockageEcsId,
|
|
55
|
+
electrique = false,
|
|
56
|
+
expected
|
|
57
|
+
}) => {
|
|
58
|
+
vi.spyOn(tvStore, 'getPertesStockage').mockReturnValue(0.32);
|
|
59
|
+
vi.spyOn(tvStore, 'getElectriqueEcsGenerateurs').mockReturnValue([2]);
|
|
60
|
+
|
|
61
|
+
/** @type {GenerateurEcsDE} */
|
|
62
|
+
const generateurEcsDE = {
|
|
63
|
+
enum_type_generateur_ecs_id: enumTypeGenerateurEcsId,
|
|
64
|
+
volume_stockage: volumeStockage,
|
|
65
|
+
enum_type_stockage_ecs_id: enumTypeStockageEcsId
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const pertesStockage = service.pertesStockage(generateurEcsDE);
|
|
69
|
+
|
|
70
|
+
if (electrique) {
|
|
71
|
+
expect(tvStore.getPertesStockage).toHaveBeenCalledWith(
|
|
72
|
+
enumTypeGenerateurEcsId,
|
|
73
|
+
volumeStockage
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
expect(pertesStockage).toBeCloseTo(expected, 2);
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
test('Ajout des données utilisateurs sur tous les générateurs', () => {
|
|
81
|
+
/** @type {InstallationEcs} */
|
|
82
|
+
const installationsEcs = {
|
|
83
|
+
generateur_ecs_collection: {
|
|
84
|
+
generateur_ecs: [
|
|
85
|
+
{
|
|
86
|
+
donnee_entree: {
|
|
87
|
+
enum_type_stockage_ecs_id: 2,
|
|
88
|
+
enum_type_energie_id: 2,
|
|
89
|
+
volume_stockage: 100
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
donnee_entree: {
|
|
94
|
+
enum_type_stockage_ecs_id: 2,
|
|
95
|
+
enum_type_energie_id: 2,
|
|
96
|
+
volume_stockage: 150
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
donnee_entree: {
|
|
101
|
+
enum_type_stockage_ecs_id: 1,
|
|
102
|
+
enum_type_energie_id: 2,
|
|
103
|
+
volume_stockage: 150
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
service.execute(installationsEcs);
|
|
111
|
+
|
|
112
|
+
expect(
|
|
113
|
+
installationsEcs.generateur_ecs_collection.generateur_ecs[0].donnee_utilisateur.Qgw
|
|
114
|
+
).toBeCloseTo(851814.112128, 2);
|
|
115
|
+
expect(
|
|
116
|
+
installationsEcs.generateur_ecs_collection.generateur_ecs[1].donnee_utilisateur.Qgw
|
|
117
|
+
).toBeCloseTo(1064620.98719, 2);
|
|
118
|
+
expect(
|
|
119
|
+
installationsEcs.generateur_ecs_collection.generateur_ecs[2].donnee_utilisateur.Qgw
|
|
120
|
+
).toBe(0);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("Determination du type d'énergie électrique du générateur", () => {
|
|
125
|
+
vi.spyOn(tvStore, 'getElectriqueEcsGenerateurs').mockReturnValue([1]);
|
|
126
|
+
expect(service.generateurElectrique({ enum_type_generateur_ecs_id: 1 })).toBeTruthy();
|
|
127
|
+
expect(service.generateurElectrique({ enum_type_generateur_ecs_id: 2 })).toBeFalsy();
|
|
128
|
+
expect(tvStore.getElectriqueEcsGenerateurs).toHaveBeenCalled();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test('Determination du type de stockage du générateur', () => {
|
|
132
|
+
expect(service.typeStockage({ enum_type_stockage_ecs_id: 1 })).toBe(TypeStockage.INSTANTANE);
|
|
133
|
+
expect(service.typeStockage({ enum_type_stockage_ecs_id: 2 })).toBe(TypeStockage.INDEPENDANT);
|
|
134
|
+
expect(service.typeStockage({ enum_type_stockage_ecs_id: 3 })).toBe(TypeStockage.INTEGRE);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { GenerateurEcsService } from './generateur-ecs.service.js';
|
|
2
|
+
import { inject } from 'dioma';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Calcul des besoins et pertes des installations ECS
|
|
6
|
+
* Données calculées
|
|
7
|
+
* — besoin_ecs : besoin en eau chaude sanitaire en mode conventionnel proratisé pour l'installation
|
|
8
|
+
* — besoin_ecs_depensier : besoin en eau chaude sanitaire en mode dépensier proratisé pour l'installation
|
|
9
|
+
* — besoin_ecs_depensier : pertes liées au stockage de l'ECS pour chaque générateur
|
|
10
|
+
* — QdwIndVc: pertes de la distribution individuelle en volume chauffé pour le mois j (Wh)
|
|
11
|
+
* — QdwColVc: pertes de la distribution collective en volume chauffé pour le mois j (Wh)
|
|
12
|
+
* — QdwColHVc: pertes de la distribution collective hors volume chauffé pour le mois j (Wh)
|
|
13
|
+
*
|
|
14
|
+
* @see Méthode de calcul 3CL-DPE 2021 (cotobre 2021) chapitre 3
|
|
15
|
+
*/
|
|
16
|
+
export class InstallationEcsService {
|
|
17
|
+
/**
|
|
18
|
+
* @type {GenerateurEcsService}
|
|
19
|
+
*/
|
|
20
|
+
#generateurEcsService;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param generateurEcsService {GenerateurEcsService}
|
|
24
|
+
*/
|
|
25
|
+
constructor(generateurEcsService = inject(GenerateurEcsService)) {
|
|
26
|
+
this.#generateurEcsService = generateurEcsService;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Détermination des besoins et pertes des installations ECS
|
|
31
|
+
*
|
|
32
|
+
* @param ctx {Contexte}
|
|
33
|
+
* @param logement {Logement}
|
|
34
|
+
* @param besoinEcs {{besoin_ecs: number, besoin_ecs_depensier: number}}
|
|
35
|
+
*/
|
|
36
|
+
execute(ctx, logement, besoinEcs) {
|
|
37
|
+
const installationsEcs = logement.installation_ecs_collection?.installation_ecs || [];
|
|
38
|
+
|
|
39
|
+
installationsEcs.forEach((installationEcs) => {
|
|
40
|
+
/**
|
|
41
|
+
* Calcul des données nécessaires au calcul pour chaque générateur (perteStockage)
|
|
42
|
+
*/
|
|
43
|
+
this.#generateurEcsService.execute(installationEcs);
|
|
44
|
+
|
|
45
|
+
const { besoinEcsInstallation, besoinEcsDepensierInstallation } = this.besoinEcsInstallation(
|
|
46
|
+
ctx,
|
|
47
|
+
installationEcs,
|
|
48
|
+
besoinEcs
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
installationEcs.donnee_intermediaire = {
|
|
52
|
+
besoin_ecs: besoinEcsInstallation,
|
|
53
|
+
besoin_ecs_depensier: besoinEcsDepensierInstallation
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Calcul des pertes de stockage et génération au niveau de l'installation
|
|
58
|
+
*/
|
|
59
|
+
this.pertesDistributionStockageEcsInstallation(
|
|
60
|
+
installationEcs,
|
|
61
|
+
besoinEcsInstallation,
|
|
62
|
+
besoinEcsDepensierInstallation
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Return true si l'installation est individuelle
|
|
69
|
+
* @param installationEcsDE {InstallationEcsDE}
|
|
70
|
+
*/
|
|
71
|
+
isInstallationIndividuelle(installationEcsDE) {
|
|
72
|
+
return parseInt(installationEcsDE.enum_type_installation_id) === 1;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Return le besoin rationalisé de l'installation par rapport au besoin glbal du logement
|
|
77
|
+
*
|
|
78
|
+
* @param ctx {Contexte}
|
|
79
|
+
* @param installationEcs {InstallationEcs}
|
|
80
|
+
* @param besoinEcs {{besoin_ecs: number, besoin_ecs_depensier: number}} besoin ECS total du logement
|
|
81
|
+
*
|
|
82
|
+
* @returns {{besoinEcsInstallation: number, besoinEcsDepensierInstallation: number}}
|
|
83
|
+
*/
|
|
84
|
+
besoinEcsInstallation(ctx, installationEcs, besoinEcs) {
|
|
85
|
+
/** @type {InstallationEcsDE} */
|
|
86
|
+
const installationEcsDE = installationEcs.donnee_entree;
|
|
87
|
+
|
|
88
|
+
let besoinEcsInstallation;
|
|
89
|
+
let besoinEcsDepensierInstallation;
|
|
90
|
+
|
|
91
|
+
const ratio =
|
|
92
|
+
(installationEcsDE.surface_habitable || ctx.surfaceHabitable) / ctx.surfaceHabitable;
|
|
93
|
+
besoinEcsInstallation = besoinEcs.besoin_ecs * ratio;
|
|
94
|
+
besoinEcsDepensierInstallation = besoinEcs.besoin_ecs_depensier * ratio;
|
|
95
|
+
|
|
96
|
+
return { besoinEcsInstallation, besoinEcsDepensierInstallation };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Pertes de distribution et stockage ECS au niveau de l'installation
|
|
101
|
+
* 15.2.3 - Consommation des auxiliaires de distribution d’ECS
|
|
102
|
+
*
|
|
103
|
+
* QdwIndVc: pertes de la distribution individuelle en volume chauffé pour le mois j (Wh)
|
|
104
|
+
* QdwColVc: pertes de la distribution collective en volume chauffé pour le mois j (Wh)
|
|
105
|
+
* QdwColHVc: pertes de la distribution collective hors volume chauffé pour le mois j (Wh)
|
|
106
|
+
*
|
|
107
|
+
* 11.6.1 - Pertes de stockage des ballons d’accumulation
|
|
108
|
+
* 11.6.2 - Pertes des ballons électriques
|
|
109
|
+
* Qgw: pertes brutes annuelles de stockage (Wh)
|
|
110
|
+
*
|
|
111
|
+
* @param installationEcs {InstallationEcs}
|
|
112
|
+
* @param besoinEcsInstallation {number}
|
|
113
|
+
* @param besoinEcsDepensierInstallation {number}
|
|
114
|
+
*/
|
|
115
|
+
pertesDistributionStockageEcsInstallation(
|
|
116
|
+
installationEcs,
|
|
117
|
+
besoinEcsInstallation,
|
|
118
|
+
besoinEcsDepensierInstallation
|
|
119
|
+
) {
|
|
120
|
+
/** @type {InstallationEcsDE}*/
|
|
121
|
+
const installationEcsDE = installationEcs.donnee_entree;
|
|
122
|
+
const installationIndividuelle = this.isInstallationIndividuelle(installationEcsDE);
|
|
123
|
+
|
|
124
|
+
installationEcs.donnee_utilisateur = {
|
|
125
|
+
QdwIndVc: {
|
|
126
|
+
conventionnel: 0.1 * besoinEcsInstallation,
|
|
127
|
+
depensier: 0.1 * besoinEcsDepensierInstallation
|
|
128
|
+
},
|
|
129
|
+
QdwColVc: {
|
|
130
|
+
conventionnel: installationIndividuelle ? 0 : 0.112 * besoinEcsInstallation,
|
|
131
|
+
depensier: installationIndividuelle ? 0 : 0.112 * besoinEcsDepensierInstallation
|
|
132
|
+
},
|
|
133
|
+
QdwColHVc: {
|
|
134
|
+
conventionnel: installationIndividuelle ? 0 : 0.028 * besoinEcsInstallation,
|
|
135
|
+
depensier: installationIndividuelle ? 0 : 0.028 * besoinEcsDepensierInstallation
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// 17.2.1.1 Calcul des consommations de chauffage, de refroidissement, d’ECS et d’auxiliaires
|
|
140
|
+
// Pour les installations ECS collectives, pas de récupération de stockage d'ECS
|
|
141
|
+
installationEcs.donnee_utilisateur.QgwRecuperable = 0;
|
|
142
|
+
if (installationIndividuelle) {
|
|
143
|
+
installationEcs.donnee_utilisateur.QgwRecuperable =
|
|
144
|
+
installationEcs.generateur_ecs_collection?.generateur_ecs
|
|
145
|
+
.filter(
|
|
146
|
+
(generateurEcs) =>
|
|
147
|
+
parseInt(generateurEcs.donnee_entree.position_volume_chauffe_stockage) === 1 ||
|
|
148
|
+
(generateurEcs.donnee_entree.position_volume_chauffe_stockage === undefined &&
|
|
149
|
+
parseInt(generateurEcs.donnee_entree.position_volume_chauffe) === 1)
|
|
150
|
+
)
|
|
151
|
+
.reduce((acc, generateurEcs) => {
|
|
152
|
+
return acc + generateurEcs.donnee_utilisateur.Qgw;
|
|
153
|
+
}, 0);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|