diff --git a/backend/Property.py b/backend/Property.py index e0d00427..966dd7cb 100644 --- a/backend/Property.py +++ b/backend/Property.py @@ -1207,6 +1207,12 @@ class Property: self.heating_energy_source = self.heating_energy_source[0] + if self.heating_energy_source == "Varied (Community Scheme)": + if self.main_fuel["fuel_type"] == "mains gas": + self.heating_energy_source = "Natural Gas (Community Scheme)" + else: + raise Exception("Implement me") + if self.hotwater["heater_type"] is not None: self.hot_water_energy_source = heater_type_to_fuel[self.hotwater["heater_type"]] else: diff --git a/backend/ml_models/AnnualBillSavings.py b/backend/ml_models/AnnualBillSavings.py index 3ee4b747..bc3a5d32 100644 --- a/backend/ml_models/AnnualBillSavings.py +++ b/backend/ml_models/AnnualBillSavings.py @@ -263,7 +263,7 @@ class AnnualBillSavings: if fuel == "Electricity": return (kwh / cop) * cls.ELECTRICITY_PRICE_CAP - if fuel == "Natural Gas": + if fuel in ["Natural Gas", "Natural Gas (Community Scheme)"]: return (kwh / cop) * cls.GAS_PRICE_CAP if fuel == "LPG": diff --git a/etl/bill_savings/data_collection.py b/etl/bill_savings/data_collection.py index 75fd9df2..49bcff82 100644 --- a/etl/bill_savings/data_collection.py +++ b/etl/bill_savings/data_collection.py @@ -134,7 +134,7 @@ def app(): for i, directory in tqdm(enumerate(epc_directories), total=len(epc_directories)): try: # Skip the first 50 - if i < 200: + if i < 256: continue data = pd.read_csv(directory / "certificates.csv", low_memory=False) diff --git a/recommendations/Recommendations.py b/recommendations/Recommendations.py index 636a43e1..d689b412 100644 --- a/recommendations/Recommendations.py +++ b/recommendations/Recommendations.py @@ -32,6 +32,12 @@ DESCRIPTIONS_TO_FUEL_TYPES = { "Room heaters, mains gas": {"fuel": 'Natural Gas', "cop": 0.9}, "Warm air, mains gas": {"fuel": 'Natural Gas', "cop": 0.9}, "Boiler, mains gas": {"fuel": 'Natural Gas', "cop": 0.9}, + "Gas multipoint": {"fuel": "Natural Gas", "cop": 0.9}, + "Warm air, Electricaire": {"fuel": "Electricity", "cop": 1}, + "Gas boiler/circulator": {"fuel": "Natural Gas", "cop": 0.9}, + "Boiler and underfloor heating, mains gas": {"fuel": "Natural Gas", "cop": 0.9}, + "No system present: electric heaters assumed": {"fuel": "Electricity", "cop": 1}, + "Electric instantaneous at point of use": {"fuel": "Electricity", "cop": 1}, } STARTING_DUMMY_ID_VALUE = -9999 @@ -517,7 +523,19 @@ class Recommendations: return property_recommendations, impact_summary @staticmethod - def map_descriptions_to_fuel(heating_description, hotwater_description): + def map_descriptions_to_fuel(heating_description, hotwater_description, main_fuel_description): + + # Handle the case of community schemes + if (heating_description == "Community scheme") or (hotwater_description == "Community scheme"): + if main_fuel_description == "mains gas (community)": + return { + "heating_fuel_type": "Natural Gas (Community Scheme)", + "hotwater_fuel_type": "Natural Gas (Community Scheme)", + "heating_cop": 1, + "hotwater_cop": 1 + } + raise NotImplementedError("Handle this case") + mapped = DESCRIPTIONS_TO_FUEL_TYPES[heating_description] heating_fuel = mapped["fuel"] @@ -529,7 +547,9 @@ class Recommendations: "heating_cop": mapped["cop"], "hotwater_cop": mapped["cop"] } - if hotwater_description == "From main system, plus solar": + if hotwater_description in [ + "From main system, plus solar", "From main system, plus solar, no cylinder thermostat" + ]: # The fuel is return { "heating_fuel_type": heating_fuel, "hotwater_fuel_type": heating_fuel + " + Solar Thermal", @@ -623,7 +643,9 @@ class Recommendations: fuel_mapping = pd.DataFrame([ { "id": epc["id"], - **cls.map_descriptions_to_fuel(epc["mainheat-description"], epc["hotwater-description"]) + **cls.map_descriptions_to_fuel( + epc["mainheat-description"], epc["hotwater-description"], epc["main-fuel"] + ) } for epc in property_instance.updated_simulation_epcs ]) @@ -635,7 +657,8 @@ class Recommendations: "id": STARTING_DUMMY_ID_VALUE, **cls.map_descriptions_to_fuel( property_instance.data["mainheat-description"], - property_instance.data["hotwater-description"] + property_instance.data["hotwater-description"], + property_instance.data["main-fuel"] ) } ] @@ -710,11 +733,15 @@ class Recommendations: rec["energy_cost_savings"] = energy_cost_savings # Finally, we set the current energy bill + # For a community scheme, there is a standing charge but it's based on the operational cost of the network + # and therefore is likely different to the typical standing charge. This will be a cost typically defined + # by the network operator and often a building, whose residents are on a heat network, where the building + # operator will purchase energy from the network and re-sell it to the residents starting_figures = kwh_impact_table[kwh_impact_table["id"] == STARTING_DUMMY_ID_VALUE].squeeze() gas_standing_charge = 0 if ( - (starting_figures["heating_fuel_type"] == "Natural Gas") or - (starting_figures["hotwater_fuel_type"] == "Natural Gas") + (starting_figures["heating_fuel_type"] in ["Natural Gas", "Natural Gas (Community Scheme)"]) or + (starting_figures["hotwater_fuel_type"] == ["Natural Gas", "Natural Gas (Community Scheme)"]) ): gas_standing_charge = AnnualBillSavings.DAILY_STANDARD_CHARGE_GAS * 365