diff --git a/src/constants/consumptionConstants/coldWater.json b/src/constants/consumptionConstants/coldWater.json new file mode 100644 index 0000000000000000000000000000000000000000..b85e887c0310c5c6985f65f205d1a738efea6f24 --- /dev/null +++ b/src/constants/consumptionConstants/coldWater.json @@ -0,0 +1,38 @@ +[ + { + "occupants_number": 1, + "consumption_in_liter_per_day": 137 + }, + { + "occupants_number": 2, + "consumption_in_liter_per_day": 274 + }, + { + "occupants_number": 3, + "consumption_in_liter_per_day": 343 + }, + { + "occupants_number": 4, + "consumption_in_liter_per_day": 412 + }, + { + "occupants_number": 5, + "consumption_in_liter_per_day": 481 + }, + { + "occupants_number": 6, + "consumption_in_liter_per_day": 550 + }, + { + "occupants_number": 7, + "consumption_in_liter_per_day": 619 + }, + { + "occupants_number": 8, + "consumption_in_liter_per_day": 688 + }, + { + "occupants_number": 9, + "consumption_in_liter_per_day": 757 + } +] diff --git a/src/constants/consumptionConstants/cooking.json b/src/constants/consumptionConstants/cooking.json new file mode 100644 index 0000000000000000000000000000000000000000..06b6742aec805bcff2dd826345100a4dd006c935 --- /dev/null +++ b/src/constants/consumptionConstants/cooking.json @@ -0,0 +1,3 @@ +{ + "ratio_kw_per_person_per_year": 200 +} diff --git a/src/constants/consumptionConstants/ecs.json b/src/constants/consumptionConstants/ecs.json new file mode 100644 index 0000000000000000000000000000000000000000..186bfadfe746739843d9d85038b249c58898795b --- /dev/null +++ b/src/constants/consumptionConstants/ecs.json @@ -0,0 +1,76 @@ +{ + "ecs_ratio": [ + { + "occupants_number": 1, + "warm_water_need_in_liter": 80 + }, + { + "occupants_number": 2, + "warm_water_need_in_liter": 120 + }, + { + "occupants_number": 3, + "warm_water_need_in_liter": 150 + }, + { + "occupants_number": 4, + "warm_water_need_in_liter": 170 + }, + { + "occupants_number": 5, + "warm_water_need_in_liter": 220 + }, + { + "occupants_number": 6, + "warm_water_need_in_liter": 265 + }, + { + "occupants_number": 7, + "warm_water_need_in_liter": 310 + }, + { + "occupants_number": 8, + "warm_water_need_in_liter": 355 + }, + { + "occupants_number": 9, + "warm_water_need_in_liter": 400 + } + ], + "mensual_repartition": [ + 111, + 120, + 111, + 106, + 103, + 93, + 84, + 72, + 92, + 103, + 104, + 101 + ], + "cold_water_temperature": [11, 11, 12, 15, 17, 19, 21, 20, 17, 15, 12, 13], + "hot_water_temperature": 40, + "solar_coverage": [ + 0.19, + 0.33, + 0.36, + 0.6, + 0.61, + 0.73, + 0.92, + 0.81, + 0.67, + 0, + 0.24, + 0.25 + ], + "efficiency_production_distribution": { + "appartment": 0.55, + "individual_house": 0.7 + }, + "coefficient_ecs_consumption": 1.163, + "coefficient_thermodynamic": 1.5 +} diff --git a/src/constants/consumptionConstants/electricSpecific.json b/src/constants/consumptionConstants/electricSpecific.json new file mode 100644 index 0000000000000000000000000000000000000000..0e5bf5ddf7863ef29185716049e238993391b967 --- /dev/null +++ b/src/constants/consumptionConstants/electricSpecific.json @@ -0,0 +1,16 @@ +{ + "individual_house": { + "before_1948": 3040, + "between_1948_and_1974": 3130, + "between_1975_and_1989": 2900, + "between_1990_and_1998": 3230, + "after_1999": 2900 + }, + "appartment": { + "before_1948": 1120, + "between_1948_and_1974": 1880, + "between_1975_and_1989": 1780, + "between_1990_and_1998": 1670, + "after_1999": 2060 + } +} diff --git a/src/constants/consumptionConstants/heating.json b/src/constants/consumptionConstants/heating.json new file mode 100644 index 0000000000000000000000000000000000000000..08ad00456453c58e2a3df757e13906079ac8488f --- /dev/null +++ b/src/constants/consumptionConstants/heating.json @@ -0,0 +1,106 @@ +{ + "heating_ratio": { + "individual_house": { + "before_1948": 196, + "between_1948_and_1974": 184, + "between_1975_and_1989": 140, + "between_1990_and_1998": 129, + "after_1999": 106 + }, + "appartment": { + "before_1948": 119, + "between_1948_and_1974": 150, + "between_1975_and_1989": 105, + "between_1990_and_1998": 73, + "after_1999": 74 + } + }, + "adjustment_outisde_facing_walls": { + "individual_house": { + "1": -0.2, + "2": -0.15, + "3": -0.1, + "4": 0 + }, + "appartment": { + "1": -0.1, + "2": 0, + "3": 0.1, + "4": 0.15 + } + }, + "adjustment_floor": { + "appartment": { + "ground_floor": 0.1, + "intermediate_floor": 0, + "last_floor": 0.15, + "not_applicable": 0 + } + }, + "adjustment_insulation": { + "before_1948": { + "none": 0, + "roof_insulation": -0.2, + "window_replacement": -0.06, + "wall_insulation": -0.15, + "window_replacement_and_wall_insulation": -0.2, + "window_replacement_and_roof_insulation": -0.25, + "roof_and_wall_insulation": -0.3, + "window_replacement_and_roof_and_wall_insulation": -0.35, + "built_after_1998": 0 + }, + "between_1948_and_1974": { + "none": 0, + "roof_insulation": -0.2, + "window_replacement": -0.06, + "wall_insulation": -0.15, + "window_replacement_and_wall_insulation": -0.2, + "window_replacement_and_roof_insulation": -0.25, + "roof_and_wall_insulation": -0.3, + "window_replacement_and_roof_and_wall_insulation": -0.35, + "built_after_1998": 0 + }, + "between_1975_and_1989": { + "none": 0, + "roof_insulation": 0, + "window_replacement": -0.06, + "wall_insulation": -0.2, + "window_replacement_and_wall_insulation": -0.25, + "window_replacement_and_roof_insulation": -0.07, + "roof_and_wall_insulation": -0.2, + "window_replacement_and_roof_and_wall_insulation": -0.25, + "built_after_1998": 0 + }, + "between_1990_and_1998": { + "none": 0, + "roof_insulation": 0, + "window_replacement": -0.04, + "wall_insulation": -0.12, + "window_replacement_and_wall_insulation": -0.15, + "window_replacement_and_roof_insulation": -0.04, + "roof_and_wall_insulation": -0.1, + "window_replacement_and_roof_and_wall_insulation": -0.15, + "built_after_1998": 0 + }, + "after_1999": { + "none": 0, + "roof_insulation": 0, + "window_replacement": 0, + "wall_insulation": 0, + "window_replacement_and_wall_insulation": 0, + "window_replacement_and_roof_insulation": 0, + "roof_and_wall_insulation": 0, + "window_replacement_and_roof_and_wall_insulation": 0, + "built_after_1998": 0 + } + }, + "adjustment_facilities": { + "none": 0, + "collective_heater": -0.1, + "individual_heater": -0.1, + "individual_ventilation": -0.05, + "individual_heater_and_ventilation": -0.12 + }, + "dju_average_by_month": [427, 363, 250, 110, 40, 4, 1, 1, 14, 102, 273, 409], + "dju_annual": 1994 +} diff --git a/src/enum/profileType.enum.ts b/src/enum/profileType.enum.ts index 1e20582f60eed0770577e7a0bddb034109f966c2..da6da9143ae5cbcb3c0bc269fc5099d252e0990b 100644 --- a/src/enum/profileType.enum.ts +++ b/src/enum/profileType.enum.ts @@ -9,12 +9,18 @@ export enum Floor { LAST_FLOOR = 'last_floor', NOT_APPLICABLE = 'not_applicable', } +export enum OutsideFacingWalls { + ONE = '1', + TWO = '2', + THREE = '3', + FOUR = '4', +} export enum ConstructionYear { BEFORE_1948 = 'before_1948', BETWEEN_1948_AND_1974 = 'between_1948_and_1974', BETWEEN_1975_AND_1989 = 'between_1975_and_1989', - BETWEEN_1990_AND_1998 = 'BETWEEN_1990_AND_1998', + BETWEEN_1990_AND_1998 = 'between_1990_and_1998', AFTER_1999 = 'after_1999', } @@ -31,6 +37,7 @@ export enum IndividualInsulationWork { WINDOW_REPLACEMENT_AND_WALL_INSULATION = 'window_replacement_and_wall_insulation', WINDOW_REPLACEMENT_AND_ROOF_INSULATION = 'window_replacement_and_roof_insulation', ROOF_AND_WALL_INSULATION = 'roof_and_wall_insulation', + WINDOW_REPLACEMENT_AND_ROOF_AND_WALL_INSULATION = 'window_replacement_and_roof_and_wall_insulation', BUILT_AFTER_1998 = 'built_after_1998', } diff --git a/src/models/profileType.model.ts b/src/models/profileType.model.ts index 1b458cd8c8c6271de579baedfb38f051e264dbd3..f9cecc57f292e1fb424ea671cf392e8ccca1f7fd 100644 --- a/src/models/profileType.model.ts +++ b/src/models/profileType.model.ts @@ -6,6 +6,7 @@ import { IndividualInsulationWork, FacilitiesInstallation, HotWaterEquipment, + OutsideFacingWalls, } from 'enum/profileType.enum' import { FluidType } from 'enum/fluid.enum' @@ -14,10 +15,10 @@ export interface ProfileType { constructionYear: ConstructionYear area: number occupantsNumber: number - outsideFacingWalls: number + outsideFacingWalls: OutsideFacingWalls floor: Floor heating: Heating - individualInsulationWork: IndividualInsulationWork[] + individualInsulationWork: IndividualInsulationWork facilitiesInstallation: FacilitiesInstallation hotWaterEquipment: HotWaterEquipment warmingFluid: FluidType diff --git a/src/services/profile.service.ts b/src/services/profile.service.ts index 1a5b8ed2ac2214e038f737e5eb950f3b17a271db..1c2753dfc70607f2ce31ef324a7b3148e3c731cb 100644 --- a/src/services/profile.service.ts +++ b/src/services/profile.service.ts @@ -10,6 +10,7 @@ import { HotWaterEquipment, HousingType, IndividualInsulationWork, + OutsideFacingWalls, } from 'enum/profileType.enum' import { FluidType } from 'enum/fluid.enum' @@ -48,12 +49,11 @@ export default class ProfileService { constructionYear: ConstructionYear.BETWEEN_1975_AND_1989, area: 100, occupantsNumber: 4, - outsideFacingWalls: 2, + outsideFacingWalls: OutsideFacingWalls.TWO, floor: Floor.NOT_APPLICABLE, heating: Heating.INDIVIDUAL, - individualInsulationWork: [ + individualInsulationWork: IndividualInsulationWork.WINDOW_REPLACEMENT_AND_WALL_INSULATION, - ], facilitiesInstallation: FacilitiesInstallation.NONE, hotWaterEquipment: HotWaterEquipment.SOLAR, warmingFluid: FluidType.ELECTRICITY, diff --git a/src/services/profileType.service.spec.ts b/src/services/profileType.service.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..70d95c5c1b50f0961193037d765c67c0de19f28c --- /dev/null +++ b/src/services/profileType.service.spec.ts @@ -0,0 +1,134 @@ +import { HotWaterEquipment } from 'enum/profileType.enum' +import { + mockCorrectedConsumption, + mockEstimatedConsumption, + mockMonthColdWaterConsumption, + mockMonthConsumption, + mockMonthConsumption1, + mockMonthConsumption2, + mockMonthCookingConsumption, + mockMonthElectricSpecificConsumption, + mockMonthEcsConsumption1Solar, + mockMonthEcsConsumptionOther, + mockMonthEcsConsumptionThermo, + mockProfileType, + mockProfileType1, + mockProfileType2, + mockwaterRawNeeds, + mockWaterSpreadNeeds, +} from '../../test/__mocks__/profileType.mock' +import ProfileTypeService from './profileType.service' + +describe('ProfileType service', () => { + const profileTypeService = new ProfileTypeService(mockProfileType) + + describe('calculateWarmingEstimatedConsumption', () => { + it('shoud calculate the Warming Estimated Consumption', () => { + const estimatedConsumption = profileTypeService.calculateWarmingEstimatedConsumption() + expect(estimatedConsumption).toEqual(mockEstimatedConsumption) + }) + + it('shoud calculate the Warming Corrected Consumption', () => { + const correctedConsumption = profileTypeService.calculateWarmingCorrectedConsumption( + mockEstimatedConsumption + ) + expect(correctedConsumption).toEqual(mockCorrectedConsumption) + }) + it('shoud calculate the Warming Month Consumption', () => { + const monthConsumption = profileTypeService.calculateWarmingMonthConsumption( + mockCorrectedConsumption, + 3 + ) + expect(monthConsumption).toEqual(mockMonthConsumption) + }) + it('shoud get the heating consumption', () => { + const monthConsumption = profileTypeService.getMonthHeating(3) + expect(monthConsumption).toEqual(mockMonthConsumption) + }) + }) + describe('shoud get the heating consumption for a flat with collective heating', () => { + const profileTypeService = new ProfileTypeService(mockProfileType1) + it('shoud get the heating consumption', () => { + const monthConsumption = profileTypeService.getMonthHeating(2) + expect(monthConsumption).toEqual(mockMonthConsumption1) + }) + }) + describe('shoud get the heating consumption for a house with individual heating, facilities, installation and individual work', () => { + const profileTypeService = new ProfileTypeService(mockProfileType2) + it('shoud get the heating consumption', () => { + const monthConsumption = profileTypeService.getMonthHeating(1) + expect(monthConsumption).toEqual(mockMonthConsumption2) + }) + }) + describe('calculateMonthWaterRawNeeds', () => { + it('shoud calculate the water raw needs consumption by month', () => { + const waterRawNeeds = profileTypeService.calculateMonthWaterRawNeeds( + mockProfileType, + 1 + ) + expect(waterRawNeeds).toEqual(mockwaterRawNeeds) + }) + + it('shoud calculate the water spread needs Consumption', () => { + const waterSpreadNeeds = profileTypeService.calculateSpreadNeeds( + mockProfileType, + 1 + ) + expect(waterSpreadNeeds).toEqual(mockWaterSpreadNeeds) + }) + it('shoud calculate the total ecs consumption by month if profileType.hotWaterEquipment === "solar"', () => { + const monthEcsConsumption = profileTypeService.calculateTotalConsumption( + mockWaterSpreadNeeds, + mockProfileType1, + 1 + ) + expect(monthEcsConsumption).toEqual(mockMonthEcsConsumption1Solar) + }) + it('shoud calculate the total ecs consumption by month if profileType.hotWaterEquipment === "other"', () => { + const mockProfileTypeWithOther = { ...mockProfileType } + mockProfileTypeWithOther.hotWaterEquipment = HotWaterEquipment.OTHER + const monthEcsConsumption = profileTypeService.calculateTotalConsumption( + mockWaterSpreadNeeds, + mockProfileTypeWithOther, + 1 + ) + expect(monthEcsConsumption).toEqual(mockMonthEcsConsumptionOther) + }) + it('shoud get the ECS consumption if profileType.hotWaterEquipment === "thermodynamic"', () => { + const monthConsumption = profileTypeService.getMonthEcs( + mockProfileType, + 1 + ) + expect(monthConsumption).toEqual(mockMonthEcsConsumptionThermo) + }) + }) + describe('shoud get the month cooking consumption', () => { + it('shoud get the month cooking consumption', () => { + const monthCookingConsumption = profileTypeService.getMonthCookingConsumption( + mockProfileType, + 1 + ) + expect(monthCookingConsumption).toEqual(mockMonthCookingConsumption) + }) + }) + describe('shoud get the month electric specific consumption', () => { + it('shoud get the electric specific consumption', () => { + const monthElectricSpecificConsumption = profileTypeService.getMonthElectricSpecificConsumption( + mockProfileType, + 1 + ) + expect(monthElectricSpecificConsumption).toEqual( + mockMonthElectricSpecificConsumption + ) + }) + }) + describe('shoud get the month cold water consumption', () => { + it('shoud get the cold water consumption', () => { + const monthColdWaterConsumption = profileTypeService.getMonthColdWaterConsumption( + mockProfileType, + 1 + ) + expect(monthColdWaterConsumption).toEqual(mockMonthColdWaterConsumption) + }) + }) +}) diff --git a/src/services/profileType.service.ts b/src/services/profileType.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..0246968f601b337d0147e399f36e69c467f7a58d --- /dev/null +++ b/src/services/profileType.service.ts @@ -0,0 +1,295 @@ +import { DateTime } from 'luxon' +import { ProfileType } from 'models/profileType.model' +import heatingData from 'constants/consumptionConstants/heating.json' +import cookingData from 'constants/consumptionConstants/cooking.json' +import elecSpeData from 'constants/consumptionConstants/electricSpecific.json' +import coldWaterData from 'constants/consumptionConstants/coldWater.json' +import EcsData from 'constants/consumptionConstants/ecs.json' +import { + ConstructionYear, + FacilitiesInstallation, + Floor, + Heating, + HotWaterEquipment, + HousingType, + IndividualInsulationWork, + OutsideFacingWalls, +} from 'enum/profileType.enum' + +export default class ProfileTypeService { + private readonly profileType: ProfileType + + constructor(profileType: ProfileType) { + this.profileType = profileType + } + /** + * calculateWarmingEstimatedConsumption + * @returns {number} Estimated consumption + */ + public calculateWarmingEstimatedConsumption(): number { + const ratiosHeating = heatingData.heating_ratio + const housingType: HousingType = this.profileType.housingType + const constructionYear: ConstructionYear = this.profileType.constructionYear + + const ratiosHeatingByHousingType = ratiosHeating[housingType] + const currentRatio: number = ratiosHeatingByHousingType[constructionYear] + const estimatedConsumption: number = this.profileType.area * currentRatio + + return estimatedConsumption + } + + /** + * calculateWarmingCorrectedConsumption + * @param {number} estimatedConsumption + * @returns {number} - Corrected consumption + */ + public calculateWarmingCorrectedConsumption( + estimatedConsumption: number + ): number { + const outsideFacingWalls: OutsideFacingWalls = this.profileType + .outsideFacingWalls + const housingType: HousingType = this.profileType.housingType + const floor: Floor = this.profileType.floor + const constructionYear: ConstructionYear = this.profileType.constructionYear + const individualInsulationWork: IndividualInsulationWork = this.profileType + .individualInsulationWork + const facilitiesInstallation: FacilitiesInstallation = this.profileType + .facilitiesInstallation + const heating = this.profileType.heating + + //Apply corrections + const correctionsNbWalls = + heatingData.adjustment_outisde_facing_walls[housingType] + const correctionWalls: number = correctionsNbWalls[outsideFacingWalls] + + let correctionFloor: number + let correctionInsulation: number + let correctionFacilities: number + + if (this.profileType.housingType === HousingType.APPARTMENT) { + correctionFloor = heatingData.adjustment_floor.appartment[floor] + } else correctionFloor = 0 + + if ( + individualInsulationWork !== IndividualInsulationWork.NONE && + constructionYear !== ConstructionYear.AFTER_1999 && + heating !== Heating.COLLECTIVE + ) { + const correctionsInsulation = + heatingData.adjustment_insulation[constructionYear] + correctionInsulation = correctionsInsulation[individualInsulationWork] + } else correctionInsulation = 0 + + if ( + facilitiesInstallation !== FacilitiesInstallation.NONE && + heating !== Heating.COLLECTIVE + ) { + correctionFacilities = + heatingData.adjustment_facilities[facilitiesInstallation] + } else correctionFacilities = 0 + + const correctedConsumption = + estimatedConsumption * + (1 + correctionFloor) * + (1 + correctionWalls) * + (1 + correctionInsulation) * + (1 + correctionFacilities) + return Math.round(correctedConsumption) + } + + /** + * calculateWarmingMonthConsumption + @param {number} correctedConsumption + @param {number} number + @returns {number} monthConsumption + */ + public calculateWarmingMonthConsumption( + correctedConsumption: number, + month: number + ): number { + const djuCurrentMonth = heatingData.dju_average_by_month[month - 1] + const monthConsumption = + (correctedConsumption / heatingData.dju_annual) * djuCurrentMonth + return Math.round(monthConsumption) + } + /** + * getMonthHeating + * @param {ProfileType} profileType + * @param {number} month + * @returns {number} Month heating consumption in kw/h + */ + public getMonthHeating(month: number): number { + const estimatedConsumption = this.calculateWarmingEstimatedConsumption() + const correctedConsumption = this.calculateWarmingCorrectedConsumption( + estimatedConsumption + ) + const monthConsumption = this.calculateWarmingMonthConsumption( + correctedConsumption, + month + ) + return monthConsumption + } + + /** + * Calculate water raw needs by month + * + * @param {ProfileType} profileType + * @param {number} month + * @returns {number} rawConsumption + */ + public calculateMonthWaterRawNeeds( + profileType: ProfileType, + month: number + ): number { + const waterNeedsIndex: number = EcsData.ecs_ratio.findIndex( + ratio => ratio.occupants_number === profileType.occupantsNumber + ) + const waterNeeds: number = + EcsData.ecs_ratio[waterNeedsIndex].warm_water_need_in_liter + const nbDaysInMonth: number = DateTime.fromObject({ + month: month, + }).setZone('utc', { + keepLocalTime: true, + }).daysInMonth + const rawConsumption: number = waterNeeds * nbDaysInMonth + return rawConsumption + } + /** + * Calculate spread water needs by month + * + * @param {ProfileType} profileType + * @param {number} month + * @returns {number} spreadConsumption + */ + public calculateSpreadNeeds(profileType: ProfileType, month: number): number { + const rawNeeds: number[] = [] + for (let index = 1; index < 13; index++) { + rawNeeds.push(this.calculateMonthWaterRawNeeds(profileType, index)) + } + const calculateTotalNeeds = ( + accumulator: number, + currentValue: number + ): number => accumulator + currentValue + const totalRawNeeds: number = rawNeeds.reduce(calculateTotalNeeds) + const spreadConsumption: number = + (totalRawNeeds / (12 * 100)) * EcsData.mensual_repartition[month - 1] + return Math.round(spreadConsumption) + } + /** + * Calculate total ecs consumption by month + * + * @param {number} spreadConsumption + * @param {ProfileType} profileType + * @returns {number} monthEcsConsumption + */ + public calculateTotalConsumption( + spreadConsumption: number, + profileType: ProfileType, + month: number + ): number { + const coldWaterTemperature: number = + EcsData.cold_water_temperature[month - 1] + const efficiencyProduction: number = + EcsData.efficiency_production_distribution[profileType.housingType] + const solarCoverage: number = EcsData.solar_coverage[month - 1] + const ecsConsumption: number = + (((EcsData.coefficient_ecs_consumption * spreadConsumption) / 1000) * + (EcsData.hot_water_temperature - coldWaterTemperature)) / + efficiencyProduction + let monthEcsConsumption: number + if (profileType.hotWaterEquipment === HotWaterEquipment.SOLAR) { + monthEcsConsumption = ecsConsumption * (1 - solarCoverage) + } else if ( + profileType.hotWaterEquipment === HotWaterEquipment.THERMODYNAMIC + ) { + monthEcsConsumption = ecsConsumption / EcsData.coefficient_thermodynamic + } else { + monthEcsConsumption = ecsConsumption + } + return Math.round(monthEcsConsumption) + } + /** + * Get ECS consumption by month + * + * @param {ProfileType} profileType + * @param {number} month + * @returns {number} monthEcsConsumption + */ + public getMonthEcs(profileType: ProfileType, month: number) { + const spreadConsumption: number = this.calculateSpreadNeeds( + profileType, + month + ) + const monthEcsConsumption: number = this.calculateTotalConsumption( + spreadConsumption, + profileType, + month + ) + return monthEcsConsumption + } + /** + * Get cooking consumption by month + * @param {ProfileType} profileType + * @param {number} month + * @returns {number} monthCookingConsumption + */ + public getMonthCookingConsumption( + profileType: ProfileType, + month: number + ): number { + const annualCookingConsumption: number = + profileType.occupantsNumber * cookingData.ratio_kw_per_person_per_year + const nbDaysInMonth: number = DateTime.fromObject({ + month: month, + }).setZone('utc', { + keepLocalTime: true, + }).daysInMonth + const monthCookingConsumption: number = + (annualCookingConsumption / 365) * nbDaysInMonth + return Math.round(monthCookingConsumption) + } + /** + * Get specific electricity consumption by month + * @param {ProfileType} profileType + * @param {number} month + * @returns {number} monthElectricSpecificConsumption + */ + public getMonthElectricSpecificConsumption( + profileType: ProfileType, + month: number + ): number { + const annualElectricSpecificConsumption: number = + elecSpeData[profileType.housingType][profileType.constructionYear] + const nbDaysInMonth: number = DateTime.fromObject({ + month: month, + }).setZone('utc', { + keepLocalTime: true, + }).daysInMonth + const monthElectricSpecificConsumption: number = + (annualElectricSpecificConsumption / 365) * nbDaysInMonth + return Math.round(monthElectricSpecificConsumption) + } + /** + * Get cold water consumption by month + * @param {ProfileType} profileType + * @param {number} month + * @returns {number} monthColdWaterConsumption + */ + public getMonthColdWaterConsumption( + profileType: ProfileType, + month: number + ): number { + const occupantsNumberIndex: number = coldWaterData.findIndex( + waterNeeds => waterNeeds.occupants_number === profileType.occupantsNumber + ) + const coldWaterNeeds: number = + coldWaterData[occupantsNumberIndex].consumption_in_liter_per_day + const nbDaysInMonth: number = DateTime.fromObject({ + month: month, + }).setZone('utc', { + keepLocalTime: true, + }).daysInMonth + const monthColdWaterConsumption: number = nbDaysInMonth * coldWaterNeeds + return Math.round(monthColdWaterConsumption) + } +} diff --git a/src/store/profile/profile.reducer.ts b/src/store/profile/profile.reducer.ts index 2c489633b04dc300a5acfca37e8a93e106c125fc..7d2a9efb3e79de62da82af777e776b437047ff2e 100644 --- a/src/store/profile/profile.reducer.ts +++ b/src/store/profile/profile.reducer.ts @@ -13,6 +13,7 @@ import { HotWaterEquipment, HousingType, IndividualInsulationWork, + OutsideFacingWalls, } from 'enum/profileType.enum' import { FluidType } from 'enum/fluid.enum' @@ -36,12 +37,11 @@ const initialState: Profile = { constructionYear: ConstructionYear.BETWEEN_1975_AND_1989, area: 100, occupantsNumber: 4, - outsideFacingWalls: 2, + outsideFacingWalls: OutsideFacingWalls.TWO, floor: Floor.NOT_APPLICABLE, heating: Heating.INDIVIDUAL, - individualInsulationWork: [ + individualInsulationWork: IndividualInsulationWork.WINDOW_REPLACEMENT_AND_WALL_INSULATION, - ], facilitiesInstallation: FacilitiesInstallation.NONE, hotWaterEquipment: HotWaterEquipment.SOLAR, warmingFluid: FluidType.ELECTRICITY, diff --git a/test/__mocks__/profile.mock.ts b/test/__mocks__/profile.mock.ts index d8e4dce242438030f3b1380fcd306e8ca4bf098e..60de4e1ee47f4421952d3d8f2a4dd2019b0b70e1 100644 --- a/test/__mocks__/profile.mock.ts +++ b/test/__mocks__/profile.mock.ts @@ -7,6 +7,7 @@ import { HotWaterEquipment, HousingType, IndividualInsulationWork, + OutsideFacingWalls, } from 'enum/profileType.enum' import { DateTime } from 'luxon' import { Profile } from 'models' @@ -36,12 +37,11 @@ export const profileData: Profile = { constructionYear: ConstructionYear.BETWEEN_1975_AND_1989, area: 100, occupantsNumber: 4, - outsideFacingWalls: 2, + outsideFacingWalls: OutsideFacingWalls.TWO, floor: Floor.NOT_APPLICABLE, heating: Heating.INDIVIDUAL, - individualInsulationWork: [ + individualInsulationWork: IndividualInsulationWork.WINDOW_REPLACEMENT_AND_WALL_INSULATION, - ], facilitiesInstallation: FacilitiesInstallation.NONE, hotWaterEquipment: HotWaterEquipment.SOLAR, warmingFluid: FluidType.ELECTRICITY, diff --git a/test/__mocks__/profileType.mock.ts b/test/__mocks__/profileType.mock.ts new file mode 100644 index 0000000000000000000000000000000000000000..e5452d0896f2e98a60685acc528943b020819b95 --- /dev/null +++ b/test/__mocks__/profileType.mock.ts @@ -0,0 +1,85 @@ +/* eslint-disable @typescript-eslint/camelcase */ +import { FluidType } from 'enum/fluid.enum' +import { + ConstructionYear, + FacilitiesInstallation, + Floor, + Heating, + HotWaterEquipment, + HousingType, + IndividualInsulationWork, + OutsideFacingWalls, +} from 'enum/profileType.enum' +import { ProfileType } from 'models/profileType.model' + +export const mockProfileType: ProfileType = { + housingType: HousingType.APPARTMENT, + constructionYear: ConstructionYear.AFTER_1999, + area: 43, + occupantsNumber: 1, + outsideFacingWalls: OutsideFacingWalls.TWO, + floor: Floor.GROUND_FLOOR, + heating: Heating.INDIVIDUAL, + individualInsulationWork: IndividualInsulationWork.NONE, + facilitiesInstallation: FacilitiesInstallation.INDIVIDUAL_HEATER, + hotWaterEquipment: HotWaterEquipment.THERMODYNAMIC, + warmingFluid: FluidType.ELECTRICITY, + hotWaterFluid: FluidType.ELECTRICITY, + cookingFluid: FluidType.ELECTRICITY, +} +export const mockEstimatedConsumption = 3182 +export const mockCorrectedConsumption = 3150 +//For the month of march +export const mockMonthConsumption = 395 + +export const mockMonthCookingConsumption = 17 + +export const mockMonthElectricSpecificConsumption = 175 + +export const mockMonthColdWaterConsumption = 4247 +export const mockwaterRawNeeds = 2480 +export const mockWaterSpreadNeeds = 2701 +export const mockMonthEcsConsumptionOther = 166 +export const mockMonthEcsConsumptionThermo = 110 + +export const mockProfileType1: ProfileType = { + housingType: HousingType.APPARTMENT, + constructionYear: ConstructionYear.BETWEEN_1948_AND_1974, + area: 43, + occupantsNumber: 2, + outsideFacingWalls: OutsideFacingWalls.TWO, + floor: Floor.INTERMEDIATE_FLOOR, + heating: Heating.COLLECTIVE, + individualInsulationWork: IndividualInsulationWork.WINDOW_REPLACEMENT, + facilitiesInstallation: FacilitiesInstallation.INDIVIDUAL_HEATER, + hotWaterEquipment: HotWaterEquipment.SOLAR, + warmingFluid: FluidType.ELECTRICITY, + hotWaterFluid: FluidType.ELECTRICITY, + cookingFluid: FluidType.ELECTRICITY, +} +export const mockEstimatedConsumption1 = 6450 +export const mockCorrectedConsumption1 = 6450 +//For the month of february +export const mockMonthConsumption1 = 1174 + +export const mockMonthEcsConsumption1Solar = 134 + +export const mockProfileType2: ProfileType = { + housingType: HousingType.INDIVIDUAL_HOUSE, + constructionYear: ConstructionYear.BETWEEN_1948_AND_1974, + area: 90, + occupantsNumber: 4, + outsideFacingWalls: OutsideFacingWalls.FOUR, + floor: Floor.GROUND_FLOOR, + heating: Heating.INDIVIDUAL, + individualInsulationWork: IndividualInsulationWork.WINDOW_REPLACEMENT, + facilitiesInstallation: FacilitiesInstallation.INDIVIDUAL_HEATER, + hotWaterEquipment: HotWaterEquipment.SOLAR, + warmingFluid: FluidType.ELECTRICITY, + hotWaterFluid: FluidType.ELECTRICITY, + cookingFluid: FluidType.ELECTRICITY, +} +export const mockEstimatedConsumption2 = 16560 +export const mockCorrectedConsumption2 = 15411 +//For the month of january +export const mockMonthConsumption2 = 3000 diff --git a/test/__mocks__/store.ts b/test/__mocks__/store.ts index 5b7dcaed75ed23d87d8b47ad807dd2e4efe0854c..74e74c5cb02167f14db0c8a89b751f3dbfc2ebdc 100644 --- a/test/__mocks__/store.ts +++ b/test/__mocks__/store.ts @@ -7,6 +7,7 @@ import { HotWaterEquipment, HousingType, IndividualInsulationWork, + OutsideFacingWalls, } from 'enum/profileType.enum' import { ScreenType } from 'enum/screen.enum' import { TimeStep } from 'enum/timeStep.enum' @@ -109,12 +110,11 @@ export const mockInitialProfileState: Profile = { constructionYear: ConstructionYear.BETWEEN_1975_AND_1989, area: 100, occupantsNumber: 4, - outsideFacingWalls: 2, + outsideFacingWalls: OutsideFacingWalls.TWO, floor: Floor.NOT_APPLICABLE, heating: Heating.INDIVIDUAL, - individualInsulationWork: [ + individualInsulationWork: IndividualInsulationWork.WINDOW_REPLACEMENT_AND_WALL_INSULATION, - ], facilitiesInstallation: FacilitiesInstallation.NONE, hotWaterEquipment: HotWaterEquipment.SOLAR, warmingFluid: FluidType.ELECTRICITY,