@open3cl/engine 1.0.5 → 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.
Files changed (68) hide show
  1. package/11_nadeq.spec.js +3 -2
  2. package/16.2_production_enr.spec.js +1 -0
  3. package/3.2.1_mur.spec.js +1 -0
  4. package/3.2.2_plancher_bas.spec.js +1 -0
  5. package/3.3_baie_vitree.spec.js +1 -0
  6. package/6.1_apport_gratuit.spec.js +1 -0
  7. package/7_inertie.spec.js +4 -3
  8. package/9_chauffage.spec.js +1 -0
  9. package/9_conso_ch.spec.js +1 -0
  10. package/9_generateur_ch.spec.js +1 -0
  11. package/conso.spec.js +1 -0
  12. package/core/assets/domain/synchronize-assets.spec.js +9 -9
  13. package/core/assets/domain/synchronize-c1-tables.spec.js +4 -4
  14. package/core/assets/domain/synchronize-dpe-ges-limit-values-tables.spec.js +6 -6
  15. package/core/assets/domain/synchronize-enum-tables.spec.js +10 -10
  16. package/core/assets/domain/synchronize-solicitations-tables.spec.js +6 -6
  17. package/core/assets/domain/synchronize-valeur-tables.spec.js +14 -14
  18. package/core/file/infrastructure/adapter/file.store.spec.js +5 -4
  19. package/core/tv/infrastructure/tvs.store.spec.js +3 -2
  20. package/core/util/infrastructure/object-util.spec.js +2 -1
  21. package/core/util/logger/log-service.js +47 -0
  22. package/features/dpe/domain/models/baie-ets.model.ts +12 -0
  23. package/features/dpe/domain/models/baie-vitree.model.ts +95 -0
  24. package/features/dpe/domain/models/climatisation.model.ts +25 -0
  25. package/features/dpe/domain/models/dpe.model.ts +194 -0
  26. package/features/dpe/domain/models/ets.model.ts +19 -0
  27. package/features/dpe/domain/models/installation-chauffage.model.ts +101 -0
  28. package/features/dpe/domain/models/installation-ecs.model.ts +76 -0
  29. package/features/dpe/domain/models/mur.model.ts +37 -0
  30. package/features/dpe/domain/models/plancher-bas.model.ts +38 -0
  31. package/features/dpe/domain/models/plancher-haut.model.ts +33 -0
  32. package/features/dpe/domain/models/pont-thermique.model.ts +21 -0
  33. package/features/dpe/domain/models/porte.model.ts +31 -0
  34. package/features/dpe/domain/models/production-elec-enr.model.ts +27 -0
  35. package/features/dpe/domain/models/sortie.model.ts +178 -0
  36. package/features/dpe/domain/models/type-habitation.model.js +8 -0
  37. package/features/dpe/domain/models/type-ventilation.model.js +8 -0
  38. package/features/dpe/domain/models/ventilation.model.ts +33 -0
  39. package/features/dpe/infrastructure/tv.store.js +389 -0
  40. package/features/dpe/infrastructure/tv.store.spec.js +690 -0
  41. package/features/engine/domain/constants.js +1 -0
  42. package/features/engine/domain/contexte.builder.js +140 -0
  43. package/features/engine/domain/contexte.builder.spec.js +152 -0
  44. package/features/engine/domain/engine.service.js +139 -0
  45. package/features/engine/domain/engine.service.spec.js +7 -0
  46. package/features/engine/domain/enveloppe/deperdition-enveloppe.service.js +262 -0
  47. package/features/engine/domain/enveloppe/deperdition-enveloppe.service.spec.js +282 -0
  48. package/features/engine/domain/enveloppe/deperdition.service.js +101 -0
  49. package/features/engine/domain/enveloppe/mur/deperdition-mur.service.js +168 -0
  50. package/features/engine/domain/enveloppe/mur/deperdition-mur.service.spec.js +345 -0
  51. package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.js +169 -0
  52. package/features/engine/domain/enveloppe/plancher_bas/deperdition-plancher-bas.service.spec.js +200 -0
  53. package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.js +136 -0
  54. package/features/engine/domain/enveloppe/plancher_haut/deperdition-plancher-haut.service.spec.js +211 -0
  55. package/features/engine/domain/enveloppe/porte/deperdition-porte.service.js +56 -0
  56. package/features/engine/domain/enveloppe/porte/deperdition-porte.service.spec.js +116 -0
  57. package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.js +338 -0
  58. package/features/engine/domain/enveloppe/ventilation/deperdition-ventilation.service.spec.js +393 -0
  59. package/features/engine/domain/models/contexte.model.ts +10 -0
  60. package/features/engine/domain/models/deperdition.model.ts +8 -0
  61. package/features/normalizer/domain/dpe-normalizer.service.js +24 -0
  62. package/features/normalizer/domain/dpe-normalizer.service.spec.js +3 -0
  63. package/ficheTechnique.spec.js +4 -3
  64. package/output.js +1 -0
  65. package/package.json +9 -8
  66. package/tv-v2.js +79121 -0
  67. package/utils.js +4 -8
  68. package/utils.spec.js +4 -3
@@ -0,0 +1,140 @@
1
+ import { TypeHabitation } from '../../dpe/domain/models/type-habitation.model.js';
2
+
3
+ /**
4
+ * Génère un contexte du logement à étudier avec des données persistées durant l'analyse
5
+ */
6
+ export class ContexteBuilder {
7
+ constructor() {}
8
+
9
+ /**
10
+ * @param dpe {Dpe}
11
+ * @return {Contexte}
12
+ */
13
+ fromDpe(dpe) {
14
+ return {
15
+ zoneClimatiqueId: dpe.logement.meteo?.enum_zone_climatique_id.toString(),
16
+ typeHabitation: this.#getTypeHabitation(dpe),
17
+ enumPeriodeConstructionId:
18
+ dpe.logement.caracteristique_generale.enum_periode_construction_id?.toString(),
19
+ effetJoule: this.#hasEffetJoule(dpe),
20
+ surfaceHabitable: this.#getSurfaceHabitable(dpe),
21
+ hauteurSousPlafond: dpe.logement.caracteristique_generale.hsp
22
+ };
23
+ }
24
+
25
+ /**
26
+ * Si un générateur de chauffage par résistance électrique existe, alors effet joule vaut vrai
27
+ * @param dpe {Dpe}
28
+ * @return {boolean}
29
+ */
30
+ #hasEffetJoule(dpe) {
31
+ return (
32
+ dpe.logement.installation_chauffage_collection?.installation_chauffage?.find((ic) =>
33
+ ic.emetteur_chauffage_collection?.emetteur_chauffage?.find(
34
+ (emetteur) => parseInt(emetteur.donnee_entree.enum_type_emission_distribution_id) <= 10
35
+ )
36
+ ) !== undefined
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Le type d'habitation est détecté à partir du type de DPE
42
+ * @param dpe {Dpe}
43
+ * @return {TypeHabitation}
44
+ */
45
+ #getTypeHabitation(dpe) {
46
+ const methodeApplication =
47
+ dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id;
48
+
49
+ if (['1', '14', '18'].includes(methodeApplication)) {
50
+ return TypeHabitation.MAISON;
51
+ } else if (
52
+ [
53
+ '2',
54
+ '3',
55
+ '4',
56
+ '5',
57
+ '10',
58
+ '11',
59
+ '12',
60
+ '13',
61
+ '15',
62
+ '16',
63
+ '19',
64
+ '20',
65
+ '22',
66
+ '23',
67
+ '24',
68
+ '25',
69
+ '31',
70
+ '32',
71
+ '33',
72
+ '34',
73
+ '35',
74
+ '36',
75
+ '37',
76
+ '38',
77
+ '39',
78
+ '40'
79
+ ].includes(methodeApplication)
80
+ ) {
81
+ return TypeHabitation.APPARTEMENT;
82
+ }
83
+ return TypeHabitation.IMMEUBLE;
84
+ }
85
+
86
+ /**
87
+ * @param dpe {Dpe}
88
+ * @return {number}
89
+ */
90
+ #getSurfaceHabitable(dpe) {
91
+ /**
92
+ * Certains DPE appartement sont générés à partir des données du DPE immeuble, la surface à prendre en compte est
93
+ * celle de l'immeuble pour les besoins ECS
94
+ * 10 - dpe appartement généré à partir des données DPE immeuble chauffage individuel ecs individuel
95
+ * 11 - dpe appartement généré à partir des données DPE immeuble chauffage collectif ecs individuel
96
+ * 12 - dpe appartement généré à partir des données DPE immeuble chauffage individuel ecs collectif
97
+ * 13 - dpe appartement généré à partir des données DPE immeuble chauffage collectif ecs collectif
98
+ * 15 - dpe issu d'une étude thermique réglementaire RT2012 bâtiment : appartement chauffage collectif ecs collectif
99
+ * 16 - dpe issu d'une étude thermique réglementaire RT2012 bâtiment : appartement chauffage individuel ecs collectif
100
+ * 19 - dpe issu d'une étude energie environement réglementaire RE2020 bâtiment : appartement chauffage collectif ecs collectif
101
+ * 20 - dpe issu d'une étude energie environement réglementaire RE2020 bâtiment : appartement chauffage individuel ecs collectif
102
+ * 22 - dpe issu d'une étude thermique réglementaire RT2012 bâtiment : appartement chauffage individuel ecs individuel
103
+ * 23 - dpe issu d'une étude thermique réglementaire RT2012 bâtiment : appartement chauffage collectif ecs individuel
104
+ * 24 - dpe issu d'une étude energie environement réglementaire RE2020 bâtiment : appartement chauffage collectif ecs individuel
105
+ * 25 - dpe issu d'une étude energie environement réglementaire RE2020 bâtiment : appartement chauffage individuel ecs individuel
106
+ * 33 - dpe appartement généré à partir des données DPE immeuble chauffage mixte (collectif-individuel) ecs individuel
107
+ * 34 - dpe appartement généré à partir des données DPE immeuble chauffage mixte (collectif-individuel) ecs collectif
108
+ * 38 - dpe appartement généré à partir des données DPE immeuble chauffage mixte (collectif-individuel) ecs mixte (collectif-individuel)
109
+ * 39 - dpe appartement généré à partir des données DPE immeuble chauffage individuel ecs mixte (collectif-individuel)
110
+ * 40 - dpe appartement généré à partir des données DPE immeuble chauffage collectif ecs mixte (collectif-individuel)
111
+ */
112
+ if (
113
+ [
114
+ '10',
115
+ '11',
116
+ '12',
117
+ '13',
118
+ '15',
119
+ '16',
120
+ '19',
121
+ '20',
122
+ '22',
123
+ '23',
124
+ '24',
125
+ '25',
126
+ '33',
127
+ '34',
128
+ '38',
129
+ '39',
130
+ '40'
131
+ ].includes(dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id)
132
+ ) {
133
+ return dpe.logement.caracteristique_generale.surface_habitable_immeuble;
134
+ }
135
+
136
+ return this.#getTypeHabitation(dpe) === TypeHabitation.IMMEUBLE
137
+ ? dpe.logement.caracteristique_generale.surface_habitable_immeuble
138
+ : dpe.logement.caracteristique_generale.surface_habitable_logement;
139
+ }
140
+ }
@@ -0,0 +1,152 @@
1
+ import { ContexteBuilder } from './contexte.builder.js';
2
+ import { beforeEach, describe, expect, test } from 'vitest';
3
+
4
+ /** @type {ContexteBuilder} **/
5
+ let contexteBuilder;
6
+
7
+ describe('Generateur du contexte du calcul', () => {
8
+ beforeEach(() => {
9
+ contexteBuilder = new ContexteBuilder();
10
+ });
11
+
12
+ test('Contexte avec effet joule', () => {
13
+ const dpe = {
14
+ logement: {
15
+ meteo: { enum_zone_climatique_id: 1 },
16
+ caracteristique_generale: {
17
+ enum_periode_construction_id: 1,
18
+ surface_habitable_logement: 48.9,
19
+ surface_habitable_immeuble: 105,
20
+ hsp: 2.8
21
+ },
22
+ installation_chauffage_collection: {
23
+ installation_chauffage: [
24
+ {
25
+ emetteur_chauffage_collection: {
26
+ emetteur_chauffage: [{ donnee_entree: { enum_type_emission_distribution_id: '1' } }]
27
+ }
28
+ }
29
+ ]
30
+ }
31
+ }
32
+ };
33
+
34
+ expect(contexteBuilder.fromDpe(dpe)).toStrictEqual({
35
+ effetJoule: true,
36
+ enumPeriodeConstructionId: '1',
37
+ zoneClimatiqueId: '1',
38
+ hauteurSousPlafond: 2.8,
39
+ surfaceHabitable: 105,
40
+ typeHabitation: 'IMMEUBLE'
41
+ });
42
+ });
43
+
44
+ test('Contexte sans effet joule', () => {
45
+ const dpe = {
46
+ logement: {
47
+ meteo: { enum_zone_climatique_id: 1 },
48
+ caracteristique_generale: {
49
+ enum_periode_construction_id: 1,
50
+ surface_habitable_logement: 48.9,
51
+ surface_habitable_immeuble: 105,
52
+ hsp: 2.8
53
+ },
54
+ installation_chauffage_collection: {
55
+ installation_chauffage: [
56
+ {
57
+ emetteur_chauffage_collection: {
58
+ emetteur_chauffage: [
59
+ { donnee_entree: { enum_type_emission_distribution_id: '12' } }
60
+ ]
61
+ }
62
+ }
63
+ ]
64
+ }
65
+ }
66
+ };
67
+
68
+ expect(contexteBuilder.fromDpe(dpe)).toStrictEqual({
69
+ effetJoule: false,
70
+ enumPeriodeConstructionId: '1',
71
+ zoneClimatiqueId: '1',
72
+ hauteurSousPlafond: 2.8,
73
+ surfaceHabitable: 105,
74
+ typeHabitation: 'IMMEUBLE'
75
+ });
76
+ });
77
+
78
+ test('Contexte sans chauffage', () => {
79
+ const dpe = {
80
+ logement: {
81
+ meteo: { enum_zone_climatique_id: 1 },
82
+ caracteristique_generale: {
83
+ enum_periode_construction_id: 1,
84
+ surface_habitable_logement: 48.9,
85
+ surface_habitable_immeuble: 105,
86
+ hsp: 2.8
87
+ }
88
+ }
89
+ };
90
+
91
+ expect(contexteBuilder.fromDpe(dpe)).toStrictEqual({
92
+ effetJoule: false,
93
+ enumPeriodeConstructionId: '1',
94
+ zoneClimatiqueId: '1',
95
+ hauteurSousPlafond: 2.8,
96
+ surfaceHabitable: 105,
97
+ typeHabitation: 'IMMEUBLE'
98
+ });
99
+ });
100
+
101
+ test('Contexte sans emetteur de chauffage', () => {
102
+ const dpe = {
103
+ logement: {
104
+ meteo: { enum_zone_climatique_id: 1 },
105
+ caracteristique_generale: {
106
+ enum_periode_construction_id: 1,
107
+ surface_habitable_logement: 48.9,
108
+ surface_habitable_immeuble: 105,
109
+ hsp: 2.8
110
+ },
111
+ installation_chauffage_collection: {}
112
+ }
113
+ };
114
+
115
+ expect(contexteBuilder.fromDpe(dpe)).toStrictEqual({
116
+ effetJoule: false,
117
+ enumPeriodeConstructionId: '1',
118
+ zoneClimatiqueId: '1',
119
+ hauteurSousPlafond: 2.8,
120
+ surfaceHabitable: 105,
121
+ typeHabitation: 'IMMEUBLE'
122
+ });
123
+ });
124
+
125
+ test('Récupération de la surface habitable du logement concerné par le DPE', () => {
126
+ let dpe = {
127
+ logement: {
128
+ caracteristique_generale: {
129
+ enum_periode_construction_id: 1,
130
+ surface_habitable_logement: 48.9,
131
+ surface_habitable_immeuble: 105,
132
+ hsp: 2.8
133
+ }
134
+ }
135
+ };
136
+
137
+ dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = '1';
138
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
139
+ surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_logement
140
+ });
141
+
142
+ dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = '5';
143
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
144
+ surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_logement
145
+ });
146
+
147
+ dpe.logement.caracteristique_generale.enum_methode_application_dpe_log_id = '8';
148
+ expect(contexteBuilder.fromDpe(dpe)).toMatchObject({
149
+ surfaceHabitable: dpe.logement.caracteristique_generale.surface_habitable_immeuble
150
+ });
151
+ });
152
+ });
@@ -0,0 +1,139 @@
1
+ import { inject } from 'dioma';
2
+ import { ContexteBuilder } from './contexte.builder.js';
3
+ import { DeperditionEnveloppeService } from './enveloppe/deperdition-enveloppe.service.js';
4
+
5
+ export class EngineService {
6
+ /**
7
+ * @type {DeperditionEnveloppeService}
8
+ */
9
+ #deperditionService;
10
+ /**
11
+ * @type {ContexteBuilder}
12
+ */
13
+ #contextBuilder;
14
+
15
+ /**
16
+ * @param deperditionService {DeperditionEnveloppeService}
17
+ * @param contextBuilder {ContexteBuilder}
18
+ */
19
+ constructor(
20
+ deperditionService = inject(DeperditionEnveloppeService),
21
+ contextBuilder = inject(ContexteBuilder)
22
+ ) {
23
+ this.#deperditionService = deperditionService;
24
+ this.#contextBuilder = contextBuilder;
25
+ }
26
+
27
+ /**
28
+ * Applique la méthode 3CL à l'entrée du DPE
29
+ * @param dpe {Dpe}
30
+ * @return {Dpe} Nouveau DPE avec les données intermédiaires et les sorties calculées
31
+ */
32
+ execute(dpe) {
33
+ /** @type {Dpe} */
34
+ const proceededDpe = this.#removeComputedData(JSON.parse(JSON.stringify(dpe)));
35
+
36
+ console.error(`Process DPE ${proceededDpe.numero_dpe}`);
37
+
38
+ proceededDpe.logement.sortie = {
39
+ deperdition: undefined,
40
+ apport_et_besoin: undefined,
41
+ ef_conso: undefined,
42
+ ep_conso: undefined,
43
+ emission_ges: undefined,
44
+ cout: undefined,
45
+ production_electricite: undefined,
46
+ sortie_par_energie_collection: undefined,
47
+ confort_ete: undefined,
48
+ qualite_isolation: undefined
49
+ };
50
+ const ctx = this.#contextBuilder.fromDpe(proceededDpe);
51
+
52
+ // Calcul de l'inertie
53
+
54
+ // Calcul des déperditions
55
+ proceededDpe.logement.sortie.deperdition = this.#deperditionService.deperditions(
56
+ ctx,
57
+ dpe.logement
58
+ );
59
+
60
+ // Calcul des déperditions par renouvellement de l'air
61
+
62
+ // Calcul de l'intermittence
63
+
64
+ // Calcul des apports gratuit
65
+
66
+ // Calcul des besoins de chauffage
67
+
68
+ // Calcul des rendements des installations
69
+
70
+ // Calcul des rendements des générations
71
+
72
+ // Calcul des rendements des générateurs ECS
73
+
74
+ // Calcul des consommations chauffage
75
+
76
+ // Calcul des consommations de froid
77
+
78
+ // Calcul des consommations ECS
79
+
80
+ // Calcul des consommations d'auxiliaires des installations de chauffage et ECS
81
+
82
+ // Calcul des consommations d'auxiliaires de ventilation
83
+
84
+ // Calcul des consommations éclairage et production d'électricités
85
+
86
+ // Calcul du DPE dans le collectif
87
+
88
+ return proceededDpe;
89
+ }
90
+
91
+ /**
92
+ * Supprime toutes les données calculées d'un DPE
93
+ * Utilisé en particulier pour les DPE déjà existant.
94
+ * @param dpe {Dpe}
95
+ * @return {Dpe} DPE sans les données intermédiaires et les sorties calculées
96
+ */
97
+ #removeComputedData(dpe) {
98
+ delete dpe.logement.sortie;
99
+ delete dpe.logement.enveloppe.inertie;
100
+
101
+ dpe.logement.enveloppe.mur_collection.mur?.map((m) => delete m.donnee_intermediaire);
102
+ dpe.logement.enveloppe.baie_vitree_collection.baie_vitree?.map((m) => {
103
+ delete m.baie_vitree_double_fenetre?.donnee_intermediaire;
104
+ delete m.donnee_intermediaire;
105
+ });
106
+ delete dpe.logement.enveloppe.ets_collection.ets?.donnee_intermediaire;
107
+ dpe.logement.enveloppe.plancher_bas_collection.plancher_bas?.map(
108
+ (m) => delete m.donnee_intermediaire
109
+ );
110
+ dpe.logement.enveloppe.plancher_haut_collection.plancher_haut?.map(
111
+ (m) => delete m.donnee_intermediaire
112
+ );
113
+ dpe.logement.enveloppe.pont_thermique_collection.pont_thermique?.map(
114
+ (m) => delete m.donnee_intermediaire
115
+ );
116
+ dpe.logement.enveloppe.porte_collection.porte?.map((m) => delete m.donnee_intermediaire);
117
+ dpe.logement.climatisation_collection.climatisation?.map((m) => delete m.donnee_intermediaire);
118
+ dpe.logement.ventilation_collection.ventilation?.map((m) => delete m.donnee_intermediaire);
119
+ dpe.logement.ventilation_collection.ventilation?.map((m) => delete m.donnee_intermediaire);
120
+ dpe.logement.installation_ecs_collection.installation_ecs?.map((m) => {
121
+ m.generateur_ecs_collection.generateur_ecs?.map((n) => {
122
+ delete n.donnee_intermediaire;
123
+ });
124
+ delete m.donnee_intermediaire;
125
+ });
126
+ dpe.logement.installation_chauffage_collection.installation_chauffage?.map((m) => {
127
+ m.emetteur_chauffage_collection.emetteur_chauffage?.map((n) => {
128
+ delete n.donnee_intermediaire;
129
+ });
130
+ m.generateur_chauffage_collection.generateur_chauffage?.map((n) => {
131
+ delete n.donnee_intermediaire;
132
+ });
133
+ delete m.donnee_intermediaire;
134
+ });
135
+ delete dpe.logement.production_elec_enr?.donnee_intermediaire;
136
+
137
+ return dpe;
138
+ }
139
+ }
@@ -0,0 +1,7 @@
1
+ import { describe, test } from 'vitest';
2
+
3
+ describe.skip('Application de la méthode 3CL', () => {
4
+ test('test complet de calcul (validation ADEME?)', () => {
5
+ // const dpe = EngineService.execute(originalDpe);=
6
+ });
7
+ });
@@ -0,0 +1,262 @@
1
+ import { inject } from 'dioma';
2
+ import { DeperditionMurService } from './mur/deperdition-mur.service.js';
3
+ import { DeperditionPorteService } from './porte/deperdition-porte.service.js';
4
+ import { DeperditionPlancherBasService } from './plancher_bas/deperdition-plancher-bas.service.js';
5
+ import { DeperditionPlancherHautService } from './plancher_haut/deperdition-plancher-haut.service.js';
6
+ import { DeperditionVentilationService } from './ventilation/deperdition-ventilation.service.js';
7
+
8
+ /**
9
+ * Calcul des déperditions de l’enveloppe
10
+ * @see Méthode de calcul 3CL-DPE 2021 (cotobre 2021) chapitre 3
11
+ */
12
+ export class DeperditionEnveloppeService {
13
+ /**
14
+ * @type {DeperditionMurService}
15
+ */
16
+ #deperditionMurService;
17
+
18
+ /**
19
+ * @type {DeperditionPorteService}
20
+ */
21
+ #deperditionPorteService;
22
+
23
+ /**
24
+ * @type {DeperditionPlancherBasService}
25
+ */
26
+ #deperditionPlancherBasService;
27
+
28
+ /**
29
+ * @type {DeperditionPlancherHautService}
30
+ */
31
+ #deperditionPlancherHautService;
32
+
33
+ /**
34
+ * @type {DeperditionVentilationService}
35
+ */
36
+ #deperditionVentilationService;
37
+
38
+ /**
39
+ * @type {number}
40
+ */
41
+ #surfaceDeperditive;
42
+
43
+ /**
44
+ * @type {number}
45
+ */
46
+ #surfaceIsolee;
47
+
48
+ /**
49
+ * @type {number}
50
+ */
51
+ #surfaceNonIsolee;
52
+
53
+ /**
54
+ * @type {number}
55
+ */
56
+ #surfaceMenuiserieAvecJoint;
57
+
58
+ /**
59
+ * @type {number}
60
+ */
61
+ #surfaceMenuiserieSansJoint;
62
+
63
+ /**
64
+ *
65
+ * @param deperditionMurService {DeperditionMurService}
66
+ * @param deperditionPorteService {DeperditionPorteService}
67
+ * @param deperditionPlancherBasService {DeperditionPlancherBasService}
68
+ * @param deperditionPlancherHautService {DeperditionPlancherHautService}
69
+ * @param deperditionVentilationService {DeperditionVentilationService}
70
+ */
71
+ constructor(
72
+ deperditionMurService = inject(DeperditionMurService),
73
+ deperditionPorteService = inject(DeperditionPorteService),
74
+ deperditionPlancherBasService = inject(DeperditionPlancherBasService),
75
+ deperditionPlancherHautService = inject(DeperditionPlancherHautService),
76
+ deperditionVentilationService = inject(DeperditionVentilationService)
77
+ ) {
78
+ this.#deperditionMurService = deperditionMurService;
79
+ this.#deperditionPorteService = deperditionPorteService;
80
+ this.#deperditionPlancherBasService = deperditionPlancherBasService;
81
+ this.#deperditionPlancherHautService = deperditionPlancherHautService;
82
+ this.#deperditionVentilationService = deperditionVentilationService;
83
+ this.#surfaceDeperditive = 0;
84
+ this.#surfaceIsolee = 0;
85
+ this.#surfaceNonIsolee = 0;
86
+ this.#surfaceMenuiserieAvecJoint = 0;
87
+ this.#surfaceMenuiserieSansJoint = 0;
88
+ }
89
+
90
+ /**
91
+ * Calcul des déperditions de l’enveloppe
92
+ * @param ctx {Contexte}
93
+ * @param logement {Logement}
94
+ * @returns {{hvent: number, hperm: number, deperdition_renouvellement_air: number, deperdition_mur: number, deperdition_plancher_bas: number, deperdition_plancher_haut: number, deperdition_baie_vitree: number, deperdition_porte: number, deperdition_pont_thermique: number, deperdition_enveloppe: number}}
95
+ */
96
+ deperditions(ctx, logement) {
97
+ const GV = this.#gv(ctx, logement.enveloppe);
98
+ const ventilation = this.#ventilation(ctx, logement);
99
+ return {
100
+ ...GV,
101
+ ...ventilation,
102
+ ...{
103
+ deperdition_enveloppe:
104
+ GV.deperdition_mur +
105
+ GV.deperdition_plancher_bas +
106
+ GV.deperdition_plancher_haut +
107
+ GV.deperdition_baie_vitree +
108
+ GV.deperdition_porte +
109
+ GV.deperdition_pont_thermique +
110
+ ventilation.hvent +
111
+ ventilation.hperm
112
+ }
113
+ };
114
+ }
115
+
116
+ /**
117
+ * Calcul des déperditions de l’enveloppe GV
118
+ *
119
+ * @param ctx {Contexte}
120
+ * @param enveloppe {Enveloppe}
121
+ *
122
+ * @return {Deperdition}
123
+ */
124
+ #gv(ctx, enveloppe) {
125
+ this.#surfaceDeperditive = 0;
126
+ this.#surfaceIsolee = 0;
127
+ this.#surfaceNonIsolee = 0;
128
+ this.#surfaceMenuiserieAvecJoint = 0;
129
+ this.#surfaceMenuiserieSansJoint = 0;
130
+
131
+ /**
132
+ * @type {Deperdition}
133
+ */
134
+ const deperditions = {
135
+ deperdition_mur: 0,
136
+ deperdition_plancher_bas: 0,
137
+ deperdition_plancher_haut: 0,
138
+ deperdition_porte: 0
139
+ };
140
+
141
+ enveloppe.mur_collection.mur?.forEach((m) => {
142
+ m.donnee_intermediaire = this.#deperditionMurService.execute(ctx, m.donnee_entree);
143
+ deperditions.deperdition_mur +=
144
+ m.donnee_intermediaire.b *
145
+ m.donnee_entree.surface_paroi_opaque *
146
+ m.donnee_intermediaire.umur;
147
+
148
+ if (m.donnee_intermediaire.b > 0) {
149
+ // Paroi déperditive si b != 0 et adjacence != 'local non déperditif'
150
+ if (m.donnee_entree.enum_type_adjacence_id !== '22') {
151
+ this.#surfaceDeperditive += m.donnee_entree.surface_paroi_opaque;
152
+ }
153
+ // Surface isolée si b != 0 et type d'isolation != 'inconnu' et != 'non isolé'
154
+ if (['1', '2'].includes(m.donnee_entree.enum_type_isolation_id)) {
155
+ this.#surfaceNonIsolee += m.donnee_entree.surface_paroi_opaque;
156
+ } else {
157
+ this.#surfaceIsolee += m.donnee_entree.surface_paroi_opaque;
158
+ }
159
+ }
160
+ });
161
+
162
+ enveloppe.porte_collection.porte?.forEach((p) => {
163
+ p.donnee_intermediaire = this.#deperditionPorteService.execute(ctx, p.donnee_entree);
164
+ deperditions.deperdition_porte +=
165
+ p.donnee_intermediaire.b * p.donnee_entree.surface_porte * p.donnee_intermediaire.uporte;
166
+
167
+ // Surface de porte déperditive si b != 0
168
+ if (p.donnee_intermediaire.b > 0) {
169
+ this.#surfaceDeperditive += p.donnee_entree.surface_porte;
170
+ }
171
+ // Surface de porte avec ou sans joint
172
+ if (p.donnee_entree.presence_joint) {
173
+ this.#surfaceMenuiserieAvecJoint += p.donnee_entree.surface_porte;
174
+ } else {
175
+ this.#surfaceMenuiserieSansJoint += p.donnee_entree.surface_porte;
176
+ }
177
+ });
178
+
179
+ const plancherBas = enveloppe.plancher_bas_collection.plancher_bas || [];
180
+ plancherBas?.forEach((pb) => {
181
+ pb.donnee_intermediaire = this.#deperditionPlancherBasService.execute(
182
+ ctx,
183
+ pb.donnee_entree,
184
+ plancherBas
185
+ );
186
+ deperditions.deperdition_plancher_bas +=
187
+ pb.donnee_intermediaire.b *
188
+ pb.donnee_entree.surface_paroi_opaque *
189
+ pb.donnee_intermediaire.upb_final;
190
+ });
191
+
192
+ enveloppe.plancher_haut_collection.plancher_haut?.forEach((ph) => {
193
+ ph.donnee_intermediaire = this.#deperditionPlancherHautService.execute(ctx, ph.donnee_entree);
194
+ deperditions.deperdition_plancher_haut +=
195
+ ph.donnee_intermediaire.b *
196
+ ph.donnee_entree.surface_paroi_opaque *
197
+ ph.donnee_intermediaire.uph;
198
+
199
+ if (ph.donnee_intermediaire.b > 0) {
200
+ // Plancher déperditif si b != 0 et adjacence != 'local non déperditif'
201
+ if (ph.donnee_entree.enum_type_adjacence_id !== '22') {
202
+ this.#surfaceDeperditive += ph.donnee_entree.surface_paroi_opaque;
203
+ }
204
+ // Surface isolée si b != 0 et type d'isolation != 'inconnu' et != 'non isolé'
205
+ if (['1', '2'].includes(ph.donnee_entree.enum_type_isolation_id)) {
206
+ this.#surfaceNonIsolee += ph.donnee_entree.surface_paroi_opaque;
207
+ } else {
208
+ this.#surfaceIsolee += ph.donnee_entree.surface_paroi_opaque;
209
+ }
210
+ }
211
+ });
212
+
213
+ enveloppe.baie_vitree_collection.baie_vitree?.forEach((bv) => {
214
+ // Surface de baie vitrée déperditive si b != 0
215
+ if (bv.donnee_intermediaire.b > 0) {
216
+ this.#surfaceDeperditive += bv.donnee_entree.surface_totale_baie;
217
+ }
218
+ // Surface de baie vitrée avec ou sans joint
219
+ if (bv.donnee_entree.presence_joint) {
220
+ this.#surfaceMenuiserieAvecJoint += bv.donnee_entree.surface_totale_baie;
221
+ } else {
222
+ this.#surfaceMenuiserieSansJoint += bv.donnee_entree.surface_totale_baie;
223
+ }
224
+ });
225
+
226
+ return deperditions;
227
+ }
228
+
229
+ /**
230
+ * Calcul des déperditions par la ventilation
231
+ *
232
+ * @param ctx {Contexte}
233
+ * @param logement {Logement}
234
+ *
235
+ * @return {Deperdition}
236
+ */
237
+ #ventilation(ctx, logement) {
238
+ /**
239
+ * @type {Deperdition}
240
+ */
241
+ const deperditions = {
242
+ hperm: 0,
243
+ hvent: 0
244
+ };
245
+
246
+ logement.ventilation_collection.ventilation?.forEach((ventilation) => {
247
+ ventilation.donnee_intermediaire = this.#deperditionVentilationService.execute(
248
+ ctx,
249
+ ventilation.donnee_entree,
250
+ this.#surfaceDeperditive,
251
+ this.#surfaceIsolee,
252
+ this.#surfaceNonIsolee,
253
+ this.#surfaceMenuiserieAvecJoint,
254
+ this.#surfaceMenuiserieSansJoint
255
+ );
256
+ deperditions.hvent += ventilation.donnee_intermediaire.hvent;
257
+ deperditions.hperm += ventilation.donnee_intermediaire.hperm;
258
+ });
259
+
260
+ return deperditions;
261
+ }
262
+ }