@open3cl/engine 1.11.2 → 1.11.3
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_rdim_ecs_individuelle_unique.js +78 -0
- package/11_rdim_ecs_individuelle_unique.spec.js +136 -0
- package/README.md +13 -13
- package/engine.js +10 -2
- package/engine.spec.js +23 -2
- package/features/dpe/domain/models/baie-ets.model.ts +8 -11
- package/features/dpe/domain/models/baie-vitree.model.ts +24 -96
- package/features/dpe/domain/models/climatisation.model.ts +13 -23
- package/features/dpe/domain/models/dpe-xsd.generated.ts +2797 -0
- package/features/dpe/domain/models/dpe.model.ts +102 -171
- package/features/dpe/domain/models/ets.model.ts +10 -18
- package/features/dpe/domain/models/installation-chauffage.model.ts +49 -102
- package/features/dpe/domain/models/installation-ecs.model.ts +27 -77
- package/features/dpe/domain/models/mur.model.ts +10 -38
- package/features/dpe/domain/models/plancher.model.ts +22 -63
- package/features/dpe/domain/models/pont-thermique.model.ts +10 -20
- package/features/dpe/domain/models/porte.model.ts +10 -30
- package/features/dpe/domain/models/production-elec-enr.model.ts +13 -27
- package/features/dpe/domain/models/sortie.model.ts +32 -176
- package/features/dpe/domain/models/ventilation.model.ts +15 -25
- package/package.json +2 -1
|
@@ -60,3 +60,81 @@ export function reconstituerRdimEcsIndividuelleUnique(th, instal_ecs, surfaceHab
|
|
|
60
60
|
instal_ecs[0].donnee_entree.rdim_reconstitue = true;
|
|
61
61
|
return true;
|
|
62
62
|
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* DPE immeuble avec plusieurs installations ECS individuelles, chacune décrite pour un logement type.
|
|
66
|
+
*
|
|
67
|
+
* Même convention d'export que l'installation unique (3.0.x, 2.0.x, 1.1.x) : pour chaque
|
|
68
|
+
* installation i, `surface_habitable` = Sh_i d'un logement type et `nombre_logement` = N_i, sans
|
|
69
|
+
* `rdim`, avec Σ Sh_i × N_i = SH. Tribu traite chaque installation indépendamment avec Rdim_i = N_i :
|
|
70
|
+
* Becs_i = Becs_immeuble × Sh_i × Rdim_i / SH / Rdim_i, puis Cecs = Σ Cecs_i × Rdim_i. L'export ADEME
|
|
71
|
+
* le confirme : besoin_ecs_i = Becs_immeuble × Sh_i / SH et conso_ecs = Σ conso_ecs_i × N_i.
|
|
72
|
+
*
|
|
73
|
+
* Sans rdim, Σ Sh_i ≠ SH : Open3CL se replie sur Becs_immeuble / nombre_appartement par
|
|
74
|
+
* installation et ne remultiplie pas la conso par N_i.
|
|
75
|
+
*
|
|
76
|
+
* Gardes :
|
|
77
|
+
* - Σ Sh_i × N_i ≈ SH (TOLERANCE_SURFACE_LOGEMENT_TYPE) : exclut les exports où Sh_i est déjà
|
|
78
|
+
* la surface totale desservie (Σ Sh_i = SH, ex. N_i fractionnaires) ;
|
|
79
|
+
* - au moins un N_i > 1 : sinon rdim = 1 partout, sans effet (LICIEL, nombre_logement = 1).
|
|
80
|
+
*
|
|
81
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - § 11.4 et § 17.1.3.2
|
|
82
|
+
* @see Tribu : Calcul_batiment.cs l. 581-588 (boucle par installation, Ratio = Sh·Rdim/SH,
|
|
83
|
+
* Becs / Rdim), l. 1660-1662 (Cecs_i / Rdim puis × Rdim) ; Calcul_installation_ECS.cs l. 75
|
|
84
|
+
* @see Guide Tribu TE-211208 « Particularités d'une répétition de systèmes d'ECS individuel dans un
|
|
85
|
+
* immeuble collectif » (Sh_ecs = surface d'un logement, Rdim = nombre d'installations identiques)
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Rdim implicites des installations ECS individuelles multiples d'un immeuble (dans l'ordre des
|
|
90
|
+
* installations), ou null si non concernées.
|
|
91
|
+
*
|
|
92
|
+
* @param th {string} type de bâtiment (maison, appartement, immeuble)
|
|
93
|
+
* @param instal_ecs {Array} installation_ecs
|
|
94
|
+
* @param surfaceHabitableImmeuble {number|string} surface habitable de l'immeuble (SH)
|
|
95
|
+
* @return {number[]|null}
|
|
96
|
+
*/
|
|
97
|
+
export function rdimsImplicitesEcsIndividuellesMultiples(th, instal_ecs, surfaceHabitableImmeuble) {
|
|
98
|
+
if (th !== 'immeuble' || !Array.isArray(instal_ecs) || instal_ecs.length < 2) return null;
|
|
99
|
+
|
|
100
|
+
const des = instal_ecs.map((inst) => inst?.donnee_entree);
|
|
101
|
+
const concernees = des.every(
|
|
102
|
+
(de) => de && String(de.enum_type_installation_id) === '1' && !de.rdim
|
|
103
|
+
);
|
|
104
|
+
if (!concernees) return null;
|
|
105
|
+
|
|
106
|
+
const SH = Number(surfaceHabitableImmeuble);
|
|
107
|
+
if (!(SH > 0)) return null;
|
|
108
|
+
|
|
109
|
+
const surfaces = des.map((de) => Number(de.surface_habitable));
|
|
110
|
+
const rdims = des.map((de) => Number(de.nombre_logement) || 1);
|
|
111
|
+
if (!surfaces.every((sh) => sh > 0) || !rdims.every((n) => n > 0)) return null;
|
|
112
|
+
if (!rdims.some((n) => n > 1)) return null;
|
|
113
|
+
|
|
114
|
+
const sommeShN = surfaces.reduce((acc, sh, i) => acc + sh * rdims[i], 0);
|
|
115
|
+
return Math.abs(sommeShN - SH) <= TOLERANCE_SURFACE_LOGEMENT_TYPE * SH ? rdims : null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Reconstitue le rdim des installations ECS individuelles multiples d'un immeuble décrites pour un
|
|
120
|
+
* logement type. Chaque installation reçoit `rdim` = nombre_logement (1 si absent) et le flag
|
|
121
|
+
* `rdim_reconstitue`.
|
|
122
|
+
*
|
|
123
|
+
* @param th {string} type de bâtiment
|
|
124
|
+
* @param instal_ecs {Array} installation_ecs
|
|
125
|
+
* @param surfaceHabitableImmeuble {number|string} surface habitable de l'immeuble (SH)
|
|
126
|
+
* @return {boolean} true si les rdim ont été reconstitués
|
|
127
|
+
*/
|
|
128
|
+
export function reconstituerRdimEcsIndividuellesMultiples(
|
|
129
|
+
th,
|
|
130
|
+
instal_ecs,
|
|
131
|
+
surfaceHabitableImmeuble
|
|
132
|
+
) {
|
|
133
|
+
const rdims = rdimsImplicitesEcsIndividuellesMultiples(th, instal_ecs, surfaceHabitableImmeuble);
|
|
134
|
+
if (rdims === null) return false;
|
|
135
|
+
instal_ecs.forEach((inst, i) => {
|
|
136
|
+
inst.donnee_entree.rdim = rdims[i];
|
|
137
|
+
inst.donnee_entree.rdim_reconstitue = true;
|
|
138
|
+
});
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vitest';
|
|
2
2
|
import {
|
|
3
3
|
rdimImpliciteEcsIndividuelleUnique,
|
|
4
|
+
rdimsImplicitesEcsIndividuellesMultiples,
|
|
4
5
|
reconstituerRdimEcsIndividuelleUnique,
|
|
6
|
+
reconstituerRdimEcsIndividuellesMultiples,
|
|
5
7
|
TOLERANCE_SURFACE_LOGEMENT_TYPE
|
|
6
8
|
} from './11_rdim_ecs_individuelle_unique.js';
|
|
7
9
|
|
|
@@ -111,3 +113,137 @@ describe("Rdim de l'installation ECS individuelle unique d'un immeuble", () => {
|
|
|
111
113
|
});
|
|
112
114
|
});
|
|
113
115
|
});
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @see Methode_de_calcul_3CL_DPE_2021-338.pdf - § 11.4 et § 17.1.3.2
|
|
119
|
+
* @see Tribu : Calcul_batiment.cs l. 581-588 et l. 1660-1662 ; Calcul_installation_ECS.cs l. 75
|
|
120
|
+
*/
|
|
121
|
+
describe("Rdim des installations ECS individuelles multiples d'un immeuble", () => {
|
|
122
|
+
/** Installation ECS individuelle décrite pour un logement type */
|
|
123
|
+
const inst = (surface_habitable, nombre_logement, de = {}) => ({
|
|
124
|
+
donnee_entree: { enum_type_installation_id: '1', surface_habitable, nombre_logement, ...de }
|
|
125
|
+
});
|
|
126
|
+
/** Cas type 2244E3039157K : 48,82 × 2 + 78,09 × 6 = 566,18 ≈ SH = 566,16 */
|
|
127
|
+
const ecs = () => [inst(48.82, 2), inst(78.09, 6)];
|
|
128
|
+
|
|
129
|
+
describe('rdimsImplicitesEcsIndividuellesMultiples', () => {
|
|
130
|
+
test('installations individuelles, Σ Sh × N = SH, sans rdim : rdim_i = nombre_logement_i', () => {
|
|
131
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', ecs(), 566.16)).toEqual([2, 6]);
|
|
132
|
+
expect(
|
|
133
|
+
rdimsImplicitesEcsIndividuellesMultiples(
|
|
134
|
+
'immeuble',
|
|
135
|
+
[
|
|
136
|
+
inst('48.82', '2', { enum_type_installation_id: 1 }),
|
|
137
|
+
inst('78.09', '6', { enum_type_installation_id: 1 })
|
|
138
|
+
],
|
|
139
|
+
'566.16'
|
|
140
|
+
)
|
|
141
|
+
).toEqual([2, 6]);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('nombre_logement absent sur une installation : rdim = 1 pour celle-ci', () => {
|
|
145
|
+
// 100 × 4 + 50 × 1 = 450
|
|
146
|
+
expect(
|
|
147
|
+
rdimsImplicitesEcsIndividuellesMultiples(
|
|
148
|
+
'immeuble',
|
|
149
|
+
[inst(100, 4), inst(50, undefined)],
|
|
150
|
+
450
|
|
151
|
+
)
|
|
152
|
+
).toEqual([4, 1]);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('tolérance de 5 % sur Σ Sh × N ≈ SH', () => {
|
|
156
|
+
// Σ = 100 × 4 + 50 × 2 = 500 ; |500 − SH| ≤ 0,05 × SH ⇔ 476,19 ≤ SH ≤ 526,31
|
|
157
|
+
const deux = () => [inst(100, 4), inst(50, 2)];
|
|
158
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 526)).toEqual([4, 2]);
|
|
159
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 477)).toEqual([4, 2]);
|
|
160
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 527)).toBeNull();
|
|
161
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', deux(), 476)).toBeNull();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('surfaces exportées comme surface totale desservie (Σ Sh = SH) : non concerné', () => {
|
|
165
|
+
// Cas type 2224E1374434V : 74,4 × 3 + 31 × 1 = 254,2 ≠ SH = 105,4 = Σ Sh
|
|
166
|
+
expect(
|
|
167
|
+
rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(74.4, 3), inst(31, 1)], 105.4)
|
|
168
|
+
).toBeNull();
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('tous les nombre_logement à 1 (LICIEL) : non concerné', () => {
|
|
172
|
+
expect(
|
|
173
|
+
rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(60, 1), inst(40, 1)], 100)
|
|
174
|
+
).toBeNull();
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('un rdim exporté sur une installation : on conserve la saisie', () => {
|
|
178
|
+
expect(
|
|
179
|
+
rdimsImplicitesEcsIndividuellesMultiples(
|
|
180
|
+
'immeuble',
|
|
181
|
+
[inst(48.82, 2, { rdim: 2 }), inst(78.09, 6)],
|
|
182
|
+
566.16
|
|
183
|
+
)
|
|
184
|
+
).toBeNull();
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test('une installation collective : non concerné', () => {
|
|
188
|
+
expect(
|
|
189
|
+
rdimsImplicitesEcsIndividuellesMultiples(
|
|
190
|
+
'immeuble',
|
|
191
|
+
[inst(48.82, 2), inst(78.09, 6, { enum_type_installation_id: '2' })],
|
|
192
|
+
566.16
|
|
193
|
+
)
|
|
194
|
+
).toBeNull();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test('maison ou appartement : non concerné', () => {
|
|
198
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('maison', ecs(), 566.16)).toBeNull();
|
|
199
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('appartement', ecs(), 566.16)).toBeNull();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test('installation unique : non concerné (cf. rdimImpliciteEcsIndividuelleUnique)', () => {
|
|
203
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(64, 10)], 640)).toBeNull();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test('données manquantes ou invalides : non concerné', () => {
|
|
207
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', undefined, 566.16)).toBeNull();
|
|
208
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', [], 566.16)).toBeNull();
|
|
209
|
+
expect(
|
|
210
|
+
rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(48.82, 2), {}], 566.16)
|
|
211
|
+
).toBeNull();
|
|
212
|
+
expect(
|
|
213
|
+
rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(48.82, 2), null], 566.16)
|
|
214
|
+
).toBeNull();
|
|
215
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', ecs(), undefined)).toBeNull();
|
|
216
|
+
expect(rdimsImplicitesEcsIndividuellesMultiples('immeuble', ecs(), 0)).toBeNull();
|
|
217
|
+
expect(
|
|
218
|
+
rdimsImplicitesEcsIndividuellesMultiples(
|
|
219
|
+
'immeuble',
|
|
220
|
+
[inst(48.82, 2), inst(undefined, 6)],
|
|
221
|
+
566.16
|
|
222
|
+
)
|
|
223
|
+
).toBeNull();
|
|
224
|
+
expect(
|
|
225
|
+
rdimsImplicitesEcsIndividuellesMultiples('immeuble', [inst(100, 4), inst(50, -2)], 300)
|
|
226
|
+
).toBeNull();
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
describe('reconstituerRdimEcsIndividuellesMultiples', () => {
|
|
231
|
+
test('installations concernées : rdim et flag positionnés sur chacune', () => {
|
|
232
|
+
const installations = ecs();
|
|
233
|
+
expect(reconstituerRdimEcsIndividuellesMultiples('immeuble', installations, 566.16)).toBe(
|
|
234
|
+
true
|
|
235
|
+
);
|
|
236
|
+
expect(installations[0].donnee_entree).toMatchObject({ rdim: 2, rdim_reconstitue: true });
|
|
237
|
+
expect(installations[1].donnee_entree).toMatchObject({ rdim: 6, rdim_reconstitue: true });
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test('installations non concernées : inchangées', () => {
|
|
241
|
+
const installations = [inst(60, 1), inst(40, 1)];
|
|
242
|
+
expect(reconstituerRdimEcsIndividuellesMultiples('immeuble', installations, 100)).toBe(false);
|
|
243
|
+
installations.forEach((i) => {
|
|
244
|
+
expect(i.donnee_entree.rdim).toBeUndefined();
|
|
245
|
+
expect(i.donnee_entree.rdim_reconstitue).toBeUndefined();
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
});
|
package/README.md
CHANGED
|
@@ -383,7 +383,7 @@ Ces résultats sont **générés automatiquement** à la fin de `npm run test:co
|
|
|
383
383
|
|
|
384
384
|
<!-- CORPUS:START -->
|
|
385
385
|
|
|
386
|
-
> **Version `1.
|
|
386
|
+
> **Version `1.11.2`** · à publier · branche `main` · généré le 2026-10-30
|
|
387
387
|
> Seuil de tolérance **5%**
|
|
388
388
|
|
|
389
389
|
<table>
|
|
@@ -416,24 +416,24 @@ Ces résultats sont **générés automatiquement** à la fin de `npm run test:co
|
|
|
416
416
|
|
|
417
417
|
<table>
|
|
418
418
|
<tr>
|
|
419
|
-
<td align="center"><strong>5,
|
|
420
|
-
<td align="center"><strong>
|
|
419
|
+
<td align="center"><strong>5,99 ms</strong><br/><sub>moyenne</sub></td>
|
|
420
|
+
<td align="center"><strong>5,23 ms</strong><br/><sub>médiane</sub></td>
|
|
421
421
|
<td align="center"><strong>0,11 ms</strong><br/><sub>min</sub></td>
|
|
422
|
-
<td align="center"><strong>
|
|
422
|
+
<td align="center"><strong>641,5 ms</strong><br/><sub>max</sub></td>
|
|
423
423
|
</tr>
|
|
424
424
|
</table>
|
|
425
425
|
|
|
426
426
|
| Corpus | Moyenne | Médiane | Min | Max | p95 | p99 |
|
|
427
427
|
| :--------------------------------------------- | ------: | ------: | ------: | -------: | ------: | ------: |
|
|
428
|
-
| **Appartement · chauffage individuel (2025)** | 4,
|
|
429
|
-
| **Appartement · chauffage collectif (2025)** | 4,
|
|
430
|
-
| **Logement individuel (2025)** | 5,
|
|
431
|
-
| **Maison individuelle (2025)** | 6,
|
|
432
|
-
| **Maison individuelle (2026)** | 6,
|
|
433
|
-
| **Immeuble · chauffage collectif** | 5,
|
|
434
|
-
| **Immeuble · chauffage individuel** | 7,
|
|
435
|
-
| **Immeuble · chauffage mixte** |
|
|
436
|
-
| **Individuel généré depuis l'immeuble (2026)** | 6,
|
|
428
|
+
| **Appartement · chauffage individuel (2025)** | 4,09 ms | 3,70 ms | 1,56 ms | 47,5 ms | 7,05 ms | 9,52 ms |
|
|
429
|
+
| **Appartement · chauffage collectif (2025)** | 4,98 ms | 4,64 ms | 1,66 ms | 41,1 ms | 8,18 ms | 10,7 ms |
|
|
430
|
+
| **Logement individuel (2025)** | 5,36 ms | 4,70 ms | 1,75 ms | 61,9 ms | 10,0 ms | 14,0 ms |
|
|
431
|
+
| **Maison individuelle (2025)** | 6,37 ms | 5,70 ms | 1,93 ms | 58,0 ms | 11,5 ms | 15,4 ms |
|
|
432
|
+
| **Maison individuelle (2026)** | 6,43 ms | 5,76 ms | 2,16 ms | 48,3 ms | 11,7 ms | 15,7 ms |
|
|
433
|
+
| **Immeuble · chauffage collectif** | 5,75 ms | 4,90 ms | 0,11 ms | 102,7 ms | 10,6 ms | 17,6 ms |
|
|
434
|
+
| **Immeuble · chauffage individuel** | 7,49 ms | 6,40 ms | 0,11 ms | 127,0 ms | 15,3 ms | 23,9 ms |
|
|
435
|
+
| **Immeuble · chauffage mixte** | 6,57 ms | 5,44 ms | 0,19 ms | 641,5 ms | 13,8 ms | 23,4 ms |
|
|
436
|
+
| **Individuel généré depuis l'immeuble (2026)** | 6,88 ms | 5,83 ms | 1,86 ms | 79,6 ms | 12,9 ms | 21,8 ms |
|
|
437
437
|
|
|
438
438
|
<sub>La moyenne est tirée vers le haut par les DPE collectifs, dont le coût atteint plusieurs
|
|
439
439
|
dizaines de fois la médiane : c’est la médiane qui décrit le cas courant, et p95/p99 le cas
|
package/engine.js
CHANGED
|
@@ -34,9 +34,12 @@ import getFicheTechnique from './ficheTechnique.js';
|
|
|
34
34
|
import { ProductionENR, ratioProrataPvLogement } from './16.2_production_enr.js';
|
|
35
35
|
import DpeSanitizerService from './dpe-sanitizer.service.js';
|
|
36
36
|
import { reconstituerRdimDpeGenereImmeuble } from './17.2_rdim_dpe_genere_immeuble.js';
|
|
37
|
-
import {
|
|
37
|
+
import {
|
|
38
|
+
reconstituerRdimEcsIndividuelleUnique,
|
|
39
|
+
reconstituerRdimEcsIndividuellesMultiples
|
|
40
|
+
} from './11_rdim_ecs_individuelle_unique.js';
|
|
38
41
|
|
|
39
|
-
const LIB_VERSION = '1.11.
|
|
42
|
+
const LIB_VERSION = '1.11.3';
|
|
40
43
|
|
|
41
44
|
const dpeSanitizerService = new DpeSanitizerService();
|
|
42
45
|
|
|
@@ -305,6 +308,11 @@ export function calcul_3cl(inputDpe, options) {
|
|
|
305
308
|
* @see https://github.com/Open3CL/engine/issues/288
|
|
306
309
|
*/
|
|
307
310
|
reconstituerRdimEcsIndividuelleUnique(th, ecs, cg.surface_habitable_immeuble);
|
|
311
|
+
/**
|
|
312
|
+
* Immeuble avec plusieurs installations ECS individuelles décrites chacune pour un logement type
|
|
313
|
+
* (Σ Sh_i × nombre_logement_i ≈ SH, sans rdim) : rdim_i = nombre_logement_i.
|
|
314
|
+
*/
|
|
315
|
+
reconstituerRdimEcsIndividuellesMultiples(th, ecs, cg.surface_habitable_immeuble);
|
|
308
316
|
const Nb_lgt = cg.nombre_appartement || 1;
|
|
309
317
|
|
|
310
318
|
/**
|
package/engine.spec.js
CHANGED
|
@@ -75,7 +75,8 @@ vi.mock('./17.2_rdim_dpe_genere_immeuble.js', () => ({
|
|
|
75
75
|
reconstituerRdimDpeGenereImmeuble: vi.fn()
|
|
76
76
|
}));
|
|
77
77
|
vi.mock('./11_rdim_ecs_individuelle_unique.js', () => ({
|
|
78
|
-
reconstituerRdimEcsIndividuelleUnique: vi.fn()
|
|
78
|
+
reconstituerRdimEcsIndividuelleUnique: vi.fn(),
|
|
79
|
+
reconstituerRdimEcsIndividuellesMultiples: vi.fn()
|
|
79
80
|
}));
|
|
80
81
|
|
|
81
82
|
// Les instances Inertie / ProductionENR sont créées au chargement du module.
|
|
@@ -129,7 +130,7 @@ const calc_confort_ete = (await import('./2021_04_13_confort_ete.js')).default;
|
|
|
129
130
|
const calc_qualite_isolation = (await import('./2021_04_13_qualite_isolation.js')).default;
|
|
130
131
|
const getFicheTechnique = (await import('./ficheTechnique.js')).default;
|
|
131
132
|
const { reconstituerRdimDpeGenereImmeuble } = await import('./17.2_rdim_dpe_genere_immeuble.js');
|
|
132
|
-
const { reconstituerRdimEcsIndividuelleUnique } =
|
|
133
|
+
const { reconstituerRdimEcsIndividuelleUnique, reconstituerRdimEcsIndividuellesMultiples } =
|
|
133
134
|
await import('./11_rdim_ecs_individuelle_unique.js');
|
|
134
135
|
|
|
135
136
|
/** Objet conso renvoyé par le mock de `calc_conso` (mêmes réf pour les 3 appels). */
|
|
@@ -1326,6 +1327,26 @@ describe('calcul_3cl - rdim de l’installation ECS individuelle unique d’un i
|
|
|
1326
1327
|
});
|
|
1327
1328
|
});
|
|
1328
1329
|
|
|
1330
|
+
describe('calcul_3cl - rdim des installations ECS individuelles multiples d’un immeuble', () => {
|
|
1331
|
+
test('reconstitution appelée avec le type de bâtiment, les installations ECS et SH, avant le calcul ECS', () => {
|
|
1332
|
+
const dpe = makeDpe();
|
|
1333
|
+
dpe.logement.caracteristique_generale.surface_habitable_immeuble = 566.16;
|
|
1334
|
+
vi.mocked(reconstituerRdimEcsIndividuellesMultiples).mockImplementationOnce(() => {
|
|
1335
|
+
expect(calc_ecs).not.toHaveBeenCalled();
|
|
1336
|
+
return false;
|
|
1337
|
+
});
|
|
1338
|
+
|
|
1339
|
+
calcul_3cl(dpe, { sanitize: false });
|
|
1340
|
+
|
|
1341
|
+
expect(reconstituerRdimEcsIndividuellesMultiples).toHaveBeenCalledWith(
|
|
1342
|
+
'maison',
|
|
1343
|
+
dpe.logement.installation_ecs_collection.installation_ecs,
|
|
1344
|
+
566.16
|
|
1345
|
+
);
|
|
1346
|
+
expect(calc_ecs).toHaveBeenCalled();
|
|
1347
|
+
});
|
|
1348
|
+
});
|
|
1349
|
+
|
|
1329
1350
|
describe('get_conso_coeff_1_7_2027', () => {
|
|
1330
1351
|
test('projette la conso EP 2027 pour une maison', () => {
|
|
1331
1352
|
vi.mocked(classe_bilan_dpe).mockReturnValue('C');
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// Alias des types générés depuis le XSD DPE (voir dpe-xsd.generated.ts). Les extensions propres
|
|
2
|
+
// à Open3CL se déclarent ici (hors fichier généré) pour survivre à la régénération.
|
|
3
|
+
import type {
|
|
4
|
+
XsdLogementEnveloppeEtsBaieEts,
|
|
5
|
+
XsdLogementEnveloppeEtsBaieEtsDonneeEntree
|
|
6
|
+
} from './dpe-xsd.generated';
|
|
2
7
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface BaieEtsDE extends DE {
|
|
8
|
-
enum_orientation_id?: number;
|
|
9
|
-
enum_inclinaison_vitrage_id?: number; // ENUM inclinaison_vitrage
|
|
10
|
-
surface_totale_baie?: number;
|
|
11
|
-
nb_baie?: number;
|
|
12
|
-
}
|
|
8
|
+
export type BaieEts = XsdLogementEnveloppeEtsBaieEts;
|
|
9
|
+
export type BaieEtsDE = XsdLogementEnveloppeEtsBaieEtsDonneeEntree;
|
|
@@ -1,97 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
// Alias des types générés depuis le XSD DPE (voir dpe-xsd.generated.ts). Les extensions propres
|
|
2
|
+
// à Open3CL se déclarent ici (hors fichier généré) pour survivre à la régénération.
|
|
3
|
+
import type {
|
|
4
|
+
XsdLogementEnveloppeBaieVitree,
|
|
5
|
+
XsdLogementEnveloppeBaieVitreeBaieVitreeDoubleFenetre,
|
|
6
|
+
XsdLogementEnveloppeBaieVitreeBaieVitreeDoubleFenetreDonneeEntree,
|
|
7
|
+
XsdLogementEnveloppeBaieVitreeBaieVitreeDoubleFenetreDonneeIntermediaire,
|
|
8
|
+
XsdLogementEnveloppeBaieVitreeDonneeEntree,
|
|
9
|
+
XsdLogementEnveloppeBaieVitreeDonneeEntreeMasqueLointainNonHomogene,
|
|
10
|
+
XsdLogementEnveloppeBaieVitreeDonneeIntermediaire
|
|
11
|
+
} from './dpe-xsd.generated';
|
|
2
12
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
enum_type_adjacence_id?: string; // ENUM type_adjacence
|
|
17
|
-
surface_totale_baie?: number;
|
|
18
|
-
nb_baie?: number;
|
|
19
|
-
tv_ug_id?: string; // TV
|
|
20
|
-
enum_type_vitrage_id?: string; // ENUM type_vitrage
|
|
21
|
-
enum_inclinaison_vitrage_id?: string; // ENUM inclinaison_vitrage
|
|
22
|
-
enum_type_gaz_lame_id?: string; // ENUM type_gaz_lame
|
|
23
|
-
epaisseur_lame?: number;
|
|
24
|
-
vitrage_vir?: boolean;
|
|
25
|
-
enum_methode_saisie_perf_vitrage_id?: string; // ENUM methode_saisie_perf_vitrage
|
|
26
|
-
ug_saisi?: number;
|
|
27
|
-
tv_uw_id?: string;
|
|
28
|
-
enum_type_materiaux_menuiserie_id?: string; // ENUM type_materiaux_menuiserie
|
|
29
|
-
enum_type_baie_id?: string; // ENUM type_baie
|
|
30
|
-
uw_saisi?: number;
|
|
31
|
-
double_fenetre?: number;
|
|
32
|
-
uw_1?: number;
|
|
33
|
-
sw_1?: number;
|
|
34
|
-
uw_2?: number;
|
|
35
|
-
sw_2?: number;
|
|
36
|
-
tv_deltar_id?: string;
|
|
37
|
-
tv_ujn_id?: string;
|
|
38
|
-
enum_type_fermeture_id?: string;
|
|
39
|
-
presence_protection_solaire_hors_fermeture?: boolean;
|
|
40
|
-
ujn_saisi?: number;
|
|
41
|
-
presence_retour_isolation?: boolean;
|
|
42
|
-
presence_joint?: boolean;
|
|
43
|
-
largeur_dormant?: number;
|
|
44
|
-
tv_sw_id?: string;
|
|
45
|
-
sw_saisi?: number;
|
|
46
|
-
enum_type_pose_id?: string; // ENUM type_pose
|
|
47
|
-
enum_orientation_id?: string;
|
|
48
|
-
tv_coef_masque_proche_id?: number;
|
|
49
|
-
tv_coef_masque_lointain_homogene_id?: number;
|
|
50
|
-
masque_lointain_non_homogene_collection: {
|
|
51
|
-
masque_lointain_non_homogene: MasqueLointainNonHomogene;
|
|
52
|
-
}[];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface BaieVitreeDI {
|
|
56
|
-
b: number;
|
|
57
|
-
ug?: number;
|
|
58
|
-
uw: number;
|
|
59
|
-
ujn?: number;
|
|
60
|
-
u_menuiserie: number;
|
|
61
|
-
sw: number;
|
|
62
|
-
fe1: number;
|
|
63
|
-
fe2: number;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export interface BaieVitreeDoubleFenetre {
|
|
67
|
-
donnee_entree?: BaieVitreeDoubleFenetreDE;
|
|
68
|
-
donnee_intermediaire?: BaieVitreeDoubleFenetreDI;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface BaieVitreeDoubleFenetreDE {
|
|
72
|
-
tv_ug_id?: string;
|
|
73
|
-
enum_type_vitrage_id: string;
|
|
74
|
-
enum_inclinaison_vitrage_id: string;
|
|
75
|
-
enum_type_gaz_lame_id?: string;
|
|
76
|
-
epaisseur_lame?: number;
|
|
77
|
-
vitrage_vir?: boolean;
|
|
78
|
-
enum_methode_saisie_perf_vitrage_id: string;
|
|
79
|
-
ug_saisi?: number;
|
|
80
|
-
tv_uw_id?: string;
|
|
81
|
-
enum_type_materiaux_menuiserie_id: string;
|
|
82
|
-
enum_type_baie_id: string;
|
|
83
|
-
uw_saisi?: number;
|
|
84
|
-
tv_sw_id?: string;
|
|
85
|
-
sw_saisi?: number;
|
|
86
|
-
enum_type_pose_id: string;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export interface BaieVitreeDoubleFenetreDI {
|
|
90
|
-
ug?: number;
|
|
91
|
-
uw: number;
|
|
92
|
-
sw: number;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export interface MasqueLointainNonHomogene {
|
|
96
|
-
tv_coef_masque_lointain_non_homogene_id?: string;
|
|
97
|
-
}
|
|
13
|
+
/** + `donnee_utilisateur` Open3CL hors XSD. */
|
|
14
|
+
export type BaieVitree = XsdLogementEnveloppeBaieVitree & {
|
|
15
|
+
donnee_utilisateur?: Record<string, any>;
|
|
16
|
+
};
|
|
17
|
+
export type BaieVitreeDE = XsdLogementEnveloppeBaieVitreeDonneeEntree;
|
|
18
|
+
export type BaieVitreeDI = XsdLogementEnveloppeBaieVitreeDonneeIntermediaire;
|
|
19
|
+
export type BaieVitreeDoubleFenetre = XsdLogementEnveloppeBaieVitreeBaieVitreeDoubleFenetre;
|
|
20
|
+
export type BaieVitreeDoubleFenetreDE =
|
|
21
|
+
XsdLogementEnveloppeBaieVitreeBaieVitreeDoubleFenetreDonneeEntree;
|
|
22
|
+
export type BaieVitreeDoubleFenetreDI =
|
|
23
|
+
XsdLogementEnveloppeBaieVitreeBaieVitreeDoubleFenetreDonneeIntermediaire;
|
|
24
|
+
export type MasqueLointainNonHomogene =
|
|
25
|
+
XsdLogementEnveloppeBaieVitreeDonneeEntreeMasqueLointainNonHomogene;
|
|
@@ -1,26 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
// Alias des types générés depuis le XSD DPE (voir dpe-xsd.generated.ts). Les extensions propres
|
|
2
|
+
// à Open3CL se déclarent ici (hors fichier généré) pour survivre à la régénération.
|
|
3
|
+
import type {
|
|
4
|
+
XsdLogementClimatisation,
|
|
5
|
+
XsdLogementClimatisationDonneeEntree,
|
|
6
|
+
XsdLogementClimatisationDonneeIntermediaire
|
|
7
|
+
} from './dpe-xsd.generated';
|
|
2
8
|
|
|
3
|
-
export interface Climatisation {
|
|
4
|
-
donnee_entree?: ClimatisationDE;
|
|
9
|
+
export interface Climatisation extends Omit<XsdLogementClimatisation, 'donnee_intermediaire'> {
|
|
5
10
|
donnee_intermediaire?: ClimatisationDI;
|
|
6
11
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
enum_methode_calcul_conso_id: number;
|
|
13
|
-
enum_periode_installation_fr_id: number;
|
|
14
|
-
cle_repartition_clim?: number;
|
|
15
|
-
enum_type_generateur_fr_id: number;
|
|
16
|
-
enum_type_energie_id?: number;
|
|
17
|
-
enum_methode_saisie_carac_sys_id: number;
|
|
18
|
-
ref_produit_fr?: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface ClimatisationDI {
|
|
22
|
-
eer: number;
|
|
23
|
-
besoin_fr: number;
|
|
24
|
-
conso_fr: number;
|
|
25
|
-
conso_fr_depensier: number;
|
|
26
|
-
}
|
|
12
|
+
export type ClimatisationDE = XsdLogementClimatisationDonneeEntree;
|
|
13
|
+
/** + champ calculé Open3CL hors XSD. */
|
|
14
|
+
export type ClimatisationDI = XsdLogementClimatisationDonneeIntermediaire & {
|
|
15
|
+
besoin_fr_depensier?: number;
|
|
16
|
+
};
|