@open3cl/engine 1.0.6 → 1.0.7
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/11_nadeq.spec.js +3 -2
- package/16.2_production_enr.spec.js +1 -0
- package/3.2.1_mur.spec.js +1 -0
- package/3.2.2_plancher_bas.spec.js +1 -0
- package/3.3_baie_vitree.spec.js +1 -0
- package/6.1_apport_gratuit.spec.js +1 -0
- package/7_inertie.spec.js +4 -3
- package/9_chauffage.spec.js +1 -0
- package/9_conso_ch.spec.js +1 -0
- package/9_generateur_ch.spec.js +1 -0
- package/conso.spec.js +1 -0
- package/core/assets/domain/synchronize-assets.spec.js +9 -9
- package/core/assets/domain/synchronize-c1-tables.spec.js +4 -4
- package/core/assets/domain/synchronize-dpe-ges-limit-values-tables.spec.js +6 -6
- package/core/assets/domain/synchronize-enum-tables.spec.js +10 -10
- package/core/assets/domain/synchronize-solicitations-tables.spec.js +6 -6
- package/core/assets/domain/synchronize-valeur-tables.spec.js +14 -14
- package/core/file/infrastructure/adapter/file.store.spec.js +5 -4
- package/core/tv/infrastructure/tvs.store.spec.js +3 -2
- package/core/util/infrastructure/object-util.spec.js +2 -1
- package/core/util/logger/log-service.js +47 -0
- package/features/dpe/domain/models/baie-ets.model.ts +12 -0
- package/features/dpe/domain/models/baie-vitree.model.ts +95 -0
- package/features/dpe/domain/models/climatisation.model.ts +25 -0
- package/features/dpe/domain/models/dpe.model.ts +194 -0
- package/features/dpe/domain/models/ets.model.ts +19 -0
- package/features/dpe/domain/models/installation-chauffage.model.ts +101 -0
- package/features/dpe/domain/models/installation-ecs.model.ts +76 -0
- package/features/dpe/domain/models/mur.model.ts +37 -0
- package/features/dpe/domain/models/plancher-bas.model.ts +38 -0
- package/features/dpe/domain/models/plancher-haut.model.ts +33 -0
- package/features/dpe/domain/models/pont-thermique.model.ts +21 -0
- package/features/dpe/domain/models/porte.model.ts +31 -0
- package/features/dpe/domain/models/production-elec-enr.model.ts +27 -0
- package/features/dpe/domain/models/sortie.model.ts +178 -0
- package/features/dpe/domain/models/type-habitation.model.js +8 -0
- package/features/dpe/domain/models/type-ventilation.model.js +8 -0
- package/features/dpe/domain/models/ventilation.model.ts +33 -0
- package/features/dpe/infrastructure/tv.store.js +389 -0
- package/features/dpe/infrastructure/tv.store.spec.js +690 -0
- package/features/engine/domain/constants.js +1 -0
- package/features/engine/domain/contexte.builder.js +140 -0
- package/features/engine/domain/contexte.builder.spec.js +152 -0
- package/features/engine/domain/engine.service.js +139 -0
- package/features/engine/domain/engine.service.spec.js +7 -0
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.js +262 -0
- package/features/engine/domain/enveloppe/deperdition-enveloppe.service.spec.js +282 -0
- package/features/engine/domain/enveloppe/deperdition.service.js +101 -0
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.js +168 -0
- package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +345 -0
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.js +169 -0
- package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +200 -0
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.js +136 -0
- package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +211 -0
- package/features/engine/domain/enveloppe/porte/deperdition-porte.service.js +56 -0
- package/features/engine/domain/enveloppe/porte/deperdition-porte.service.spec.js +116 -0
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.js +338 -0
- package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +393 -0
- package/features/engine/domain/models/contexte.model.ts +10 -0
- package/features/engine/domain/models/deperdition.model.ts +8 -0
- package/features/normalizer/domain/dpe-normalizer.service.js +24 -0
- package/features/normalizer/domain/dpe-normalizer.service.spec.js +3 -0
- package/ficheTechnique.spec.js +4 -3
- package/output.js +1 -0
- package/package.json +9 -8
- package/tv-v2.js +79121 -0
- package/utils.js +2 -2
- package/utils.spec.js +4 -3
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { DeperditionEnveloppeService } from './deperdition-enveloppe.service.js';
|
|
2
|
+
import corpus from '../../../../../test/corpus-sano.json';
|
|
3
|
+
import { getAdemeFileJson } from '../../../../../test/test-helpers.js';
|
|
4
|
+
import { ContexteBuilder } from '../contexte.builder.js';
|
|
5
|
+
import { DeperditionPlancherBasService } from './plancher_bas/deperdition-plancher-bas.service.js';
|
|
6
|
+
import { DeperditionMurService } from './mur/deperdition-mur.service.js';
|
|
7
|
+
import { DeperditionPorteService } from './porte/deperdition-porte.service.js';
|
|
8
|
+
import { DeperditionPlancherHautService } from './plancher_haut/deperdition-plancher-haut.service.js';
|
|
9
|
+
import { DpeNormalizerService } from '../../../normalizer/domain/dpe-normalizer.service.js';
|
|
10
|
+
import { TvStore } from '../../../dpe/infrastructure/tv.store.js';
|
|
11
|
+
import { beforeEach, describe, expect, test } from 'vitest';
|
|
12
|
+
import b from '../../../../3.1_b.js';
|
|
13
|
+
|
|
14
|
+
/** @type {DeperditionPorteService} **/
|
|
15
|
+
let deperditionPorteService;
|
|
16
|
+
|
|
17
|
+
/** @type {DeperditionMurService} **/
|
|
18
|
+
let deperditionMurService;
|
|
19
|
+
|
|
20
|
+
/** @type {DeperditionPlancherBasService} **/
|
|
21
|
+
let deperditionPlancherBasService;
|
|
22
|
+
|
|
23
|
+
/** @type {DeperditionPlancherHautService} **/
|
|
24
|
+
let deperditionPlancherHautService;
|
|
25
|
+
|
|
26
|
+
/** @type {DpeNormalizerService} **/
|
|
27
|
+
let normalizerService;
|
|
28
|
+
|
|
29
|
+
/** @type {ContexteBuilder} **/
|
|
30
|
+
let contexteBuilder;
|
|
31
|
+
|
|
32
|
+
/** @type {TvStore} **/
|
|
33
|
+
let tvStore;
|
|
34
|
+
|
|
35
|
+
/** @type {DeperditionEnveloppeService} **/
|
|
36
|
+
let service;
|
|
37
|
+
|
|
38
|
+
describe('Calcul des déperditions', () => {
|
|
39
|
+
beforeEach(() => {
|
|
40
|
+
tvStore = new TvStore();
|
|
41
|
+
deperditionPorteService = new DeperditionPorteService(tvStore);
|
|
42
|
+
deperditionMurService = new DeperditionMurService(tvStore);
|
|
43
|
+
deperditionPlancherBasService = new DeperditionPlancherBasService(tvStore);
|
|
44
|
+
deperditionPlancherHautService = new DeperditionPlancherHautService(tvStore);
|
|
45
|
+
normalizerService = new DpeNormalizerService();
|
|
46
|
+
contexteBuilder = new ContexteBuilder();
|
|
47
|
+
|
|
48
|
+
service = new DeperditionEnveloppeService(
|
|
49
|
+
deperditionMurService,
|
|
50
|
+
deperditionPorteService,
|
|
51
|
+
deperditionPlancherBasService,
|
|
52
|
+
deperditionPlancherHautService
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
describe('Détermination du coefficient de réduction des déperditions b', () => {
|
|
57
|
+
test.each([
|
|
58
|
+
{ enumTypeAdjacenceId: '1', label: 'extérieur', bExpected: 1 },
|
|
59
|
+
{ enumTypeAdjacenceId: '2', label: 'paroi enterrée', bExpected: 1 },
|
|
60
|
+
{ enumTypeAdjacenceId: '3', label: 'vide sanitaire', bExpected: 1 },
|
|
61
|
+
{
|
|
62
|
+
enumTypeAdjacenceId: '4',
|
|
63
|
+
label: "bâtiment ou local à usage autre que d'habitation",
|
|
64
|
+
bExpected: 0.2
|
|
65
|
+
},
|
|
66
|
+
{ enumTypeAdjacenceId: '5', label: 'terre-plein', bExpected: 1 },
|
|
67
|
+
{ enumTypeAdjacenceId: '6', label: 'sous-sol non chauffé', bExpected: 1 },
|
|
68
|
+
{
|
|
69
|
+
enumTypeAdjacenceId: '7',
|
|
70
|
+
enumCfgIsolationLncId: '1',
|
|
71
|
+
label: 'locaux non chauffés non accessible',
|
|
72
|
+
bExpected: 0.95
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
enumTypeAdjacenceId: '8',
|
|
76
|
+
surfaceAiu: 14.75,
|
|
77
|
+
surfaceAue: 300,
|
|
78
|
+
enumCfgIsolationLncId: '2',
|
|
79
|
+
label: 'garage',
|
|
80
|
+
bExpected: 0.9
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
enumTypeAdjacenceId: '9',
|
|
84
|
+
surfaceAiu: 8.14,
|
|
85
|
+
surfaceAue: 22.8,
|
|
86
|
+
enumCfgIsolationLncId: '4',
|
|
87
|
+
label: 'cellier',
|
|
88
|
+
bExpected: 0.95
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
enumTypeAdjacenceId: '10',
|
|
92
|
+
surfaceAiu: 8.14,
|
|
93
|
+
surfaceAue: 22.8,
|
|
94
|
+
enumCfgIsolationLncId: '9',
|
|
95
|
+
label: 'espace tampon solarisé (véranda,loggia fermée)',
|
|
96
|
+
bExpected: undefined
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
enumTypeAdjacenceId: '10',
|
|
100
|
+
surfaceAiu: 8.14,
|
|
101
|
+
surfaceAue: 22.8,
|
|
102
|
+
zoneClimatiqueId: '5',
|
|
103
|
+
enumCfgIsolationLncId: '9',
|
|
104
|
+
label: 'espace tampon solarisé (véranda,loggia fermée)',
|
|
105
|
+
bExpected: 0.85
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
enumTypeAdjacenceId: '11',
|
|
109
|
+
surfaceAiu: 50.2,
|
|
110
|
+
surfaceAue: 60,
|
|
111
|
+
enumCfgIsolationLncId: '4',
|
|
112
|
+
label: 'comble fortement ventilé',
|
|
113
|
+
bExpected: 0.95
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
enumTypeAdjacenceId: '12',
|
|
117
|
+
surfaceAiu: 74,
|
|
118
|
+
surfaceAue: 110,
|
|
119
|
+
enumCfgIsolationLncId: '4',
|
|
120
|
+
label: 'comble faiblement ventilé',
|
|
121
|
+
bExpected: 0.95
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
enumTypeAdjacenceId: '13',
|
|
125
|
+
surfaceAiu: 30,
|
|
126
|
+
surfaceAue: 45,
|
|
127
|
+
enumCfgIsolationLncId: '2',
|
|
128
|
+
label: 'comble très faiblement ventilé',
|
|
129
|
+
bExpected: 0.65
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
enumTypeAdjacenceId: '14',
|
|
133
|
+
surfaceAiu: 22,
|
|
134
|
+
surfaceAue: 15,
|
|
135
|
+
enumCfgIsolationLncId: '2',
|
|
136
|
+
label: "circulation sans ouverture directe sur l'extérieur",
|
|
137
|
+
bExpected: 0.35
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
enumTypeAdjacenceId: '15',
|
|
141
|
+
surfaceAiu: 20,
|
|
142
|
+
surfaceAue: 2.5,
|
|
143
|
+
enumCfgIsolationLncId: '2',
|
|
144
|
+
label: "circulation avec ouverture directe sur l'extérieur",
|
|
145
|
+
bExpected: 0.15
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
enumTypeAdjacenceId: '16',
|
|
149
|
+
surfaceAiu: 120,
|
|
150
|
+
surfaceAue: 300,
|
|
151
|
+
enumCfgIsolationLncId: '3',
|
|
152
|
+
label: 'circulation avec bouche ou gaine de désenfumage ouverte en permanence',
|
|
153
|
+
bExpected: 0.7
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
enumTypeAdjacenceId: '17',
|
|
157
|
+
label: "hall d'entrée avec dispositif de fermeture automatique",
|
|
158
|
+
bExpected: 0
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
enumTypeAdjacenceId: '18',
|
|
162
|
+
surfaceAiu: 335.22,
|
|
163
|
+
surfaceAue: 29.18,
|
|
164
|
+
enumCfgIsolationLncId: '2',
|
|
165
|
+
label: "hall d'entrée sans dispositif de fermeture automatique",
|
|
166
|
+
bExpected: 0.15
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
enumTypeAdjacenceId: '19',
|
|
170
|
+
surfaceAiu: 49,
|
|
171
|
+
surfaceAue: 65,
|
|
172
|
+
enumCfgIsolationLncId: '2',
|
|
173
|
+
label: 'garage privé collectif',
|
|
174
|
+
bExpected: 0.7
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
enumTypeAdjacenceId: '20',
|
|
178
|
+
label: "local tertiaire à l'intérieur de l'immeuble en contact avec l'appartement",
|
|
179
|
+
bExpected: 0.2
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
enumTypeAdjacenceId: '21',
|
|
183
|
+
surfaceAiu: 4.94,
|
|
184
|
+
surfaceAue: 8.8,
|
|
185
|
+
enumCfgIsolationLncId: '2',
|
|
186
|
+
label: 'autres dépendances',
|
|
187
|
+
bExpected: 0.75
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
enumTypeAdjacenceId: '22',
|
|
191
|
+
label: "local non déperditif (local à usage d'habitation chauffé)",
|
|
192
|
+
bExpected: 0
|
|
193
|
+
}
|
|
194
|
+
])(
|
|
195
|
+
'$label (id:$enumTypeAdjacenceId)',
|
|
196
|
+
({
|
|
197
|
+
enumTypeAdjacenceId,
|
|
198
|
+
surfaceAiu = undefined,
|
|
199
|
+
surfaceAue = undefined,
|
|
200
|
+
zoneClimatiqueId = undefined,
|
|
201
|
+
enumCfgIsolationLncId = undefined,
|
|
202
|
+
bExpected
|
|
203
|
+
}) => {
|
|
204
|
+
const data = {
|
|
205
|
+
enumTypeAdjacenceId,
|
|
206
|
+
surfaceAiu,
|
|
207
|
+
surfaceAue,
|
|
208
|
+
enumCfgIsolationLncId,
|
|
209
|
+
zoneClimatiqueId
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const b = deperditionMurService.b(data);
|
|
213
|
+
expect(b).toBe(bExpected);
|
|
214
|
+
}
|
|
215
|
+
);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
describe.skip('Benchmark', () => {
|
|
219
|
+
test('reworked', () => {
|
|
220
|
+
const data = {
|
|
221
|
+
enumTypeAdjacenceId: '8',
|
|
222
|
+
surfaceAiu: 2.82,
|
|
223
|
+
surfaceAue: 300,
|
|
224
|
+
enumCfgIsolationLncId: '2',
|
|
225
|
+
label: 'garage'
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
for (let i = 0; i < 1000; i++) {
|
|
229
|
+
const b = deperditionMurService.b(data);
|
|
230
|
+
expect(b).toBe(0.9);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test('legacy', () => {
|
|
235
|
+
const di = { b: undefined };
|
|
236
|
+
const de = {
|
|
237
|
+
enum_type_adjacence_id: '8',
|
|
238
|
+
surface_aiu: 2.82,
|
|
239
|
+
surface_aue: 300,
|
|
240
|
+
enum_cfg_isolation_lnc_id: '2'
|
|
241
|
+
};
|
|
242
|
+
const du = {};
|
|
243
|
+
const zc = '1';
|
|
244
|
+
|
|
245
|
+
for (let i = 0; i < 1000; i++) {
|
|
246
|
+
b(di, de, du, zc);
|
|
247
|
+
expect(di.b).toBe(0.9);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
describe("Test d'intégration de calcul des deperditions", () => {
|
|
253
|
+
test.each(corpus)('deperditions pour dpe %s', (ademeId) => {
|
|
254
|
+
let dpeRequest = getAdemeFileJson(ademeId);
|
|
255
|
+
dpeRequest = normalizerService.normalize(dpeRequest);
|
|
256
|
+
|
|
257
|
+
/** @type {Contexte} */
|
|
258
|
+
const ctx = contexteBuilder.fromDpe(dpeRequest);
|
|
259
|
+
/** @type {Logement} */
|
|
260
|
+
const logement = dpeRequest.logement;
|
|
261
|
+
/** @type {Deperdition} */
|
|
262
|
+
const deperditions = service.deperditions(ctx, logement);
|
|
263
|
+
|
|
264
|
+
expect(deperditions.deperdition_mur).toBeCloseTo(
|
|
265
|
+
dpeRequest.logement.sortie.deperdition.deperdition_mur,
|
|
266
|
+
1
|
|
267
|
+
);
|
|
268
|
+
expect(deperditions.deperdition_porte).toBeCloseTo(
|
|
269
|
+
dpeRequest.logement.sortie.deperdition.deperdition_porte,
|
|
270
|
+
1
|
|
271
|
+
);
|
|
272
|
+
expect(deperditions.deperdition_plancher_bas).toBeCloseTo(
|
|
273
|
+
dpeRequest.logement.sortie.deperdition.deperdition_plancher_bas,
|
|
274
|
+
1
|
|
275
|
+
);
|
|
276
|
+
expect(deperditions.deperdition_plancher_haut).toBeCloseTo(
|
|
277
|
+
dpeRequest.logement.sortie.deperdition.deperdition_plancher_haut,
|
|
278
|
+
1
|
|
279
|
+
);
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import enums from '../../../../enums.js';
|
|
2
|
+
import { logger } from '../../../../core/util/logger/log-service.js';
|
|
3
|
+
import { inject } from 'dioma';
|
|
4
|
+
import { TvStore } from '../../../dpe/infrastructure/tv.store.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Calcul des déperditions de l’enveloppe GV
|
|
8
|
+
* @see Méthode de calcul 3CL-DPE 2021 (cotobre 2021) chapitre 3
|
|
9
|
+
*/
|
|
10
|
+
export class DeperditionService {
|
|
11
|
+
/**
|
|
12
|
+
* @type {TvStore}
|
|
13
|
+
*/
|
|
14
|
+
tvStore;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param tvStore {TvStore}
|
|
18
|
+
*/
|
|
19
|
+
constructor(tvStore = inject(TvStore)) {
|
|
20
|
+
this.tvStore = tvStore;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Détermination des déperditions pour l'enveloppe concernée
|
|
25
|
+
* @param ctx {Contexte}
|
|
26
|
+
* @param de {DE}
|
|
27
|
+
* @return void
|
|
28
|
+
*/
|
|
29
|
+
/* eslint-disable no-unused-vars */
|
|
30
|
+
execute(ctx, de) {
|
|
31
|
+
throw new Error('Unsupported operation');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Détermination du coefficient de réduction des déperditions b
|
|
36
|
+
* @see Méthode de calcul 3CL-DPE 2021 (cotobre 2021) chapitre 3.1
|
|
37
|
+
*
|
|
38
|
+
* @param d {DeperditionData}
|
|
39
|
+
* @return {number|undefined} Retourne le coefficient de réduction des déperditions b ou undefined si le calcul est impossible
|
|
40
|
+
*/
|
|
41
|
+
b(d) {
|
|
42
|
+
let uVue,
|
|
43
|
+
zc,
|
|
44
|
+
rAiuAue = undefined;
|
|
45
|
+
let enumTypeAdjacenceId = d.enumTypeAdjacenceId;
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
['8', '9', '11', '12', '13', '14', '15', '16', '17', '18', '19', '21'].includes(
|
|
49
|
+
enumTypeAdjacenceId
|
|
50
|
+
)
|
|
51
|
+
) {
|
|
52
|
+
if (!d.surfaceAue || d.surfaceAue === 0) {
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @see Méthode de calcul 3CL-DPE 2021 (cotobre 2021)
|
|
58
|
+
* chapitre 3.1 Détermination du coefficient de réduction des déperditions b
|
|
59
|
+
* 'Dans le cas de locaux non chauffés non accessibles (mitoyenneté, espace sans accès…), forfaitairement b = 0,95.'
|
|
60
|
+
*/
|
|
61
|
+
if (d.enumCfgIsolationLncId === '1') {
|
|
62
|
+
enumTypeAdjacenceId = undefined;
|
|
63
|
+
} else {
|
|
64
|
+
uVue = this.tvStore.getUVue(enumTypeAdjacenceId) || 0;
|
|
65
|
+
rAiuAue = d.surfaceAiu / d.surfaceAue;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Type d'adjacence 10: 'espace tampon solarisé (véranda,loggia fermée)'
|
|
71
|
+
* Prise en compte de la zone climatique
|
|
72
|
+
*/
|
|
73
|
+
if (['10'].includes(enumTypeAdjacenceId)) {
|
|
74
|
+
if (!d.zoneClimatiqueId) {
|
|
75
|
+
logger.warn(
|
|
76
|
+
`impossible de calculer b pour TypeAdjacenceId:${enumTypeAdjacenceId} sans zone climatique`
|
|
77
|
+
);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
zc = enums.zone_climatique[parseInt(d.zoneClimatiqueId)];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return this.tvStore.getB(enumTypeAdjacenceId, uVue, d.enumCfgIsolationLncId, rAiuAue, zc);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Si Année d'isolation connue alors on prend cette donnée.
|
|
88
|
+
* Sinon
|
|
89
|
+
* Si Année de construction ≤74 alors Année d’isolation = 75-77
|
|
90
|
+
* Sinon Année d’isolation = Année de construction
|
|
91
|
+
*
|
|
92
|
+
* @param enumPeriodeIsolationId {number}
|
|
93
|
+
* @param ctx {Contexte}
|
|
94
|
+
* @return {string} ID de la période d'isolation
|
|
95
|
+
*/
|
|
96
|
+
getEnumPeriodeIsolationId(enumPeriodeIsolationId, ctx) {
|
|
97
|
+
return (
|
|
98
|
+
enumPeriodeIsolationId || Math.max(parseInt(ctx.enumPeriodeConstructionId), 3).toString()
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { logger } from '../../../../../core/util/logger/log-service.js';
|
|
2
|
+
import { inject } from 'dioma';
|
|
3
|
+
import { PRECISION } from '../../constants.js';
|
|
4
|
+
import { DeperditionService } from '../deperdition.service.js';
|
|
5
|
+
import { TvStore } from '../../../../dpe/infrastructure/tv.store.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Calcul des déperditions de l’enveloppe GV
|
|
9
|
+
* Chapitre 3.2.1 Calcul des Umur
|
|
10
|
+
*
|
|
11
|
+
* Méthode de calcul 3CL-DPE 2021
|
|
12
|
+
* Octobre 2021
|
|
13
|
+
* @see consolide_anne…arrete_du_31_03_2021_relatif_aux_methodes_et_procedures_applicables.pdf
|
|
14
|
+
*/
|
|
15
|
+
export class DeperditionMurService extends DeperditionService {
|
|
16
|
+
/**
|
|
17
|
+
* @param tvStore {TvStore}
|
|
18
|
+
*/
|
|
19
|
+
constructor(tvStore = inject(TvStore)) {
|
|
20
|
+
super(tvStore);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param ctx {Contexte}
|
|
25
|
+
* @param murDE {MurDE}
|
|
26
|
+
* @return {MurDI}
|
|
27
|
+
*/
|
|
28
|
+
execute(ctx, murDE) {
|
|
29
|
+
const umur0 = this.#umur0(murDE);
|
|
30
|
+
const umur = this.#umur(murDE, umur0, ctx);
|
|
31
|
+
const b = this.b({
|
|
32
|
+
enumTypeAdjacenceId: murDE.enum_type_adjacence_id,
|
|
33
|
+
surfaceAiu: murDE.surface_aiu,
|
|
34
|
+
surfaceAue: murDE.surface_aue,
|
|
35
|
+
enumCfgIsolationLncId: murDE.enum_cfg_isolation_lnc_id,
|
|
36
|
+
tvCoefReductionDeperditionId: murDE.tv_coef_reduction_deperdition_id,
|
|
37
|
+
zoneClimatiqueId: ctx.zoneClimatiqueId
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
/** @type {MurDI} */
|
|
41
|
+
return { umur0, umur, b };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param murDE {MurDE}
|
|
46
|
+
* @param umur0 {number}
|
|
47
|
+
* @param ctx {Contexte}
|
|
48
|
+
* @return {number|undefined}
|
|
49
|
+
*/
|
|
50
|
+
#umur(murDE, umur0, ctx) {
|
|
51
|
+
// On determine umur_nu (soit umur0 soit 2.5 comme valeur minimale forfaitaire)
|
|
52
|
+
const umurNu = Math.min(umur0, 2.5);
|
|
53
|
+
|
|
54
|
+
const enumPeriodeIsolationId = this.getEnumPeriodeIsolationId(
|
|
55
|
+
murDE.enum_periode_isolation_id,
|
|
56
|
+
ctx
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// Selon l'isolation, on applique un calcul au mur nu pour simuler son isolation
|
|
60
|
+
let umur;
|
|
61
|
+
switch (murDE.enum_methode_saisie_u_id) {
|
|
62
|
+
case '1': // non isolé
|
|
63
|
+
umur = umurNu;
|
|
64
|
+
break;
|
|
65
|
+
case '2': // isolation inconnue (table forfaitaire)
|
|
66
|
+
umur = Math.min(
|
|
67
|
+
umurNu,
|
|
68
|
+
this.tvStore.getUmur(ctx.enumPeriodeConstructionId, ctx.zoneClimatiqueId, ctx.effetJoule)
|
|
69
|
+
);
|
|
70
|
+
break;
|
|
71
|
+
case '7': // année d'isolation différente de l'année de construction
|
|
72
|
+
case '8': // année de construction saisie
|
|
73
|
+
umur = Math.min(
|
|
74
|
+
umurNu,
|
|
75
|
+
this.tvStore.getUmur(enumPeriodeIsolationId, ctx.zoneClimatiqueId, ctx.effetJoule)
|
|
76
|
+
);
|
|
77
|
+
break;
|
|
78
|
+
case '3': // epaisseur isolation saisie justifiée par mesure ou observation
|
|
79
|
+
case '4': {
|
|
80
|
+
// epaisseur isolation saisie (en cm)
|
|
81
|
+
const epaisseurIsolation = murDE.epaisseur_isolation;
|
|
82
|
+
if (epaisseurIsolation) {
|
|
83
|
+
umur = 1 / (1 / umurNu + (murDE.epaisseur_isolation * 0.01) / 0.04);
|
|
84
|
+
} else {
|
|
85
|
+
logger.warn(
|
|
86
|
+
`Le mur ${murDE.description} ne possède pas de donnée d'entrée pour epaisseur_isolation
|
|
87
|
+
alors que methode_saisie_u = 'epaisseur isolation saisie'`
|
|
88
|
+
);
|
|
89
|
+
umur = Math.min(umur0, 2.5);
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
case '5':
|
|
94
|
+
case '6':
|
|
95
|
+
// resistance isolation saisie
|
|
96
|
+
umur = 1 / (1 / umurNu + murDE.resistance_isolation);
|
|
97
|
+
break;
|
|
98
|
+
default:
|
|
99
|
+
// saisie direct de la valeur de u
|
|
100
|
+
umur = murDE.umur_saisi;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return Math.round(parseFloat(umur) * PRECISION) / PRECISION;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @param murDE {MurDE}
|
|
109
|
+
* @return {number|undefined}
|
|
110
|
+
*/
|
|
111
|
+
#umur0(murDE) {
|
|
112
|
+
let umur0;
|
|
113
|
+
switch (murDE.enum_methode_saisie_u0_id) {
|
|
114
|
+
case '1':
|
|
115
|
+
umur0 = this.tvStore.getUmur0(murDE.enum_materiaux_structure_mur_id);
|
|
116
|
+
break;
|
|
117
|
+
case '2':
|
|
118
|
+
umur0 = this.tvStore.getUmur0(
|
|
119
|
+
murDE.enum_materiaux_structure_mur_id,
|
|
120
|
+
murDE.epaisseur_structure
|
|
121
|
+
);
|
|
122
|
+
break;
|
|
123
|
+
case '5':
|
|
124
|
+
// Valeur u saisie directement umur0 vide
|
|
125
|
+
return;
|
|
126
|
+
default:
|
|
127
|
+
// Valeur saisie
|
|
128
|
+
return murDE.umur0_saisi;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Pour l’ensemble des parois, la présence d’un doublage apporte une résistance thermique supplémentaire
|
|
133
|
+
*/
|
|
134
|
+
switch (murDE.enum_type_doublage_id) {
|
|
135
|
+
case '3':
|
|
136
|
+
// doublage indéterminé ou lame d'air inf 15 mm
|
|
137
|
+
umur0 = 1 / (1 / umur0 + 0.1);
|
|
138
|
+
break;
|
|
139
|
+
case '4': // doublage indéterminé ou lame d'air sup 15 mm
|
|
140
|
+
case '5': // doublage connu (plâtre brique bois)
|
|
141
|
+
umur0 = 1 / (1 / umur0 + 0.21);
|
|
142
|
+
break;
|
|
143
|
+
default:
|
|
144
|
+
// absence de doublage ou inconnu
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Pour les parois dites « anciennes », c’est-à-dire constituées de matériaux traditionnels à savoir pierres, terre, mur à
|
|
150
|
+
* colombage, brique ancienne, la présence d’un enduit isolant n’est pas considérée comme une isolation. Cependant,
|
|
151
|
+
* cet enduit apporte une correction d’isolation qu’il faut prendre en compte
|
|
152
|
+
*
|
|
153
|
+
* la paroi est une paroi ancienne sur laquelle a été appliquée un enduit isolant (Renduit=0,7m².K.W-1) 0 : non 1 : oui.
|
|
154
|
+
* (Attention ! nom de propriété pas tout à fait explicite)
|
|
155
|
+
* OBSOLETE > remplacé par enduit_isolant_paroi_ancienne
|
|
156
|
+
*/
|
|
157
|
+
if (murDE.enduit_isolant_paroi_ancienne) {
|
|
158
|
+
umur0 = 1 / (1 / umur0 + 0.7);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @todo Comportement non clairement documenté
|
|
163
|
+
* Dans beaucoup de cas umur0 retourné en le min entre 2.5 et la valeur trouvée,
|
|
164
|
+
* mais pas de documentation sur ce point dans la méthode 3CL
|
|
165
|
+
*/
|
|
166
|
+
return Math.min(2.5, Math.round(parseFloat(umur0) * PRECISION) / PRECISION);
|
|
167
|
+
}
|
|
168
|
+
}
|