added patch to built for form newhaven

This commit is contained in:
Khalim Conn-Kowlessar 2024-08-14 12:20:17 +01:00
parent 1e16babab3
commit 7e973d7955
6 changed files with 86 additions and 22 deletions

View file

@ -93,6 +93,7 @@ class Property:
self.data = {
k.replace("_", "-"): v for k, v in epc_record.get("prepared_epc").items()
}
self.old_data = epc_record.get("old_data")
self.property_dimensions = None
# This is a list of measures that have already been installed in the property, typically found as a result
@ -1193,6 +1194,11 @@ class Property:
if self.hotwater["heater_type"] is not None:
self.hot_water_energy_source = heater_type_to_fuel[self.hotwater["heater_type"]]
if self.hotwater["extra_features"] == "plus solar":
self.hot_water_energy_source = self.heating_energy_source + " + Solar Thermal"
return
else:
fuel = system_type_modification[self.hotwater["system_type"]]

View file

@ -312,7 +312,17 @@ def get_on_site_data(body: PlanTriggerRequest):
return patches, already_installed, non_invasive_recommendations
def extract_propert_on_site_recommendations(config, already_installed, non_invasive_recommendations, uprn):
def extract_property_on_site_recommendations(config, patches, already_installed, non_invasive_recommendations, uprn):
patch_has_uprn = "uprn" in patches[0]
if patch_has_uprn:
patch = next((
x for x in patches if str(x["uprn"]) == str(config["uprn"])
), {})
else:
patch = next((
x for x in patches if (x["address"] == config["address"]) and (x["postcode"] == config["postcode"])
), {})
property_already_installed = next((
x for x in already_installed if
(x["address"] == config["address"]) and (x["postcode"] == config["postcode"])
@ -348,7 +358,7 @@ def extract_propert_on_site_recommendations(config, already_installed, non_invas
property_non_invasive_recommendations["recommendations"] = str(transformed)
return property_already_installed, property_non_invasive_recommendations
return patch, property_already_installed, property_non_invasive_recommendations
router = APIRouter(
@ -423,9 +433,13 @@ async def trigger_plan(body: PlanTriggerRequest):
epc_records, energy_assessment["energy_assessment_is_newer"] = create_epc_records(
epc_searcher, energy_assessment
)
patch = next((
x for x in patches if (x["address"] == config["address"]) and (x["postcode"] == config["postcode"])
), {})
patch, property_already_installed, property_non_invasive_recommendations = (
extract_property_on_site_recommendations(
config, patches, already_installed, non_invasive_recommendations, uprn
)
)
epc_records = patch_epc(patch, epc_records)
prepared_epc = EPCRecord(
@ -434,10 +448,6 @@ async def trigger_plan(body: PlanTriggerRequest):
cleaning_data=cleaning_data
)
property_already_installed, property_non_invasive_recommendations = extract_propert_on_site_recommendations(
config, already_installed, non_invasive_recommendations, uprn
)
input_properties.append(
Property(
id=property_id,
@ -509,6 +519,7 @@ async def trigger_plan(body: PlanTriggerRequest):
# TODO: For simple properties, we should do a comparison/check between the solar API's roof area and the
# basic estimate of roof area
# TODO: Debug this
building_ids = [
{
"building_id": p.building_id,
@ -797,12 +808,6 @@ async def trigger_plan(body: PlanTriggerRequest):
]
recommendations[p.id] = final_recommendations
# With that complete, we now total the kwh and cost savings for the property
# total_kwh_savings = sum([rec["kwh_savings"] for rec in final_recommendations if rec["default"]])
# total_energy_cost_savings = sum(
# [rec["energy_cost_savings"] for rec in final_recommendations if rec["default"]]
# )
logger.info("Uploading recommendations to the database")
# If we have any work to do, we create a new scenario
engine_scenario = create_scenario(

View file

@ -35,6 +35,7 @@ class PlanTriggerRequest(BaseModel):
"air_source_heat_pump",
"internal_wall_insulation",
"external_wall_insulation",
"secondary_heating"
}
_allowed_goals = {"Increasing EPC"}

View file

@ -285,6 +285,10 @@ class AnnualBillSavings:
# The solar thermal covers a % of the heating kwh, so we need to adjust the cost
return (kwh / cop) * assumptions.SOLAR_CONSUMPTION_PROPORTION * cls.GAS_PRICE_CAP
if fuel == "Electricity + Solar Thermal":
# The solar thermal covers a % of the heating kwh, so we need to adjust the cost
return (kwh / cop) * assumptions.SOLAR_CONSUMPTION_PROPORTION * cls.ELECTRICITY_PRICE_CAP
if fuel == "Oil":
price_data = cls.FUEL_DATA[cls.FUEL_DATA["Fuel"] == "Kerosene"].squeeze()
cost_per_kwh = cls.cost_per_kwh(

View file

@ -11,7 +11,7 @@ EPC_DIRECTORY = Path(src_file_path).parent / "local_data" / "all-domestic-certif
CUSTOMER_DATA_DIRECTORY = "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Newhaven/Data"
USER_ID = 8
PORTFOLIO_ID = 89
PORTFOLIO_ID = 90
def make_asset_list():
@ -109,8 +109,8 @@ def make_asset_list():
asset_list = asset_list[asset_list["Class Description"] != "Caravan"]
asset_list = asset_list[~pd.isnull(asset_list["current-energy-efficiency"])]
# Take a 10% sample, for properties that have an EPC, with a seed
asset_list = asset_list.sample(frac=0.25, random_state=42)
# Take a sample, for properties that have an EPC, with a seed
# asset_list = asset_list.sample(frac=0.5, random_state=42)
AVG_FLOOR_HEIGHT = asset_list["floor-height"].median()
@ -195,6 +195,17 @@ def make_asset_list():
property_non_invasive_recs = []
if not property_ashp_potential.empty:
if property_costs.empty:
similar_properties = ashp_potential[
ashp_potential["Overall Suitability Rating"] &
(ashp_potential["Recommended Heat Pump Size [kW]"] ==
property_ashp_potential["Recommended Heat Pump Size [kW]"].values[0])
].merge(
renewables_cost, how="inner", on="UPRN"
)
property_costs = similar_properties[["Air Source Heat Pump - Total"]].mean().to_frame().T
property_non_invasive_recs.append(
{
"type": "air_source_heat_pump",
@ -256,6 +267,21 @@ def make_asset_list():
file_name=non_invasive_recommendations_filename
)
# We add a patch to one of the units because there's no data for the built form
# We would be able to handle this automatically in the future, when using OS API
patches = [{
"uprn": "10033266220",
"built-form": "Semi-Detached",
}]
# Store patches in s3
patches_filename = f"{USER_ID}/{PORTFOLIO_ID}/patches.json"
save_csv_to_s3(
dataframe=pd.DataFrame(patches),
bucket_name="retrofit-plan-inputs-dev",
file_name=patches_filename
)
# Create three scenarios
body1 = {
"portfolio_id": str(PORTFOLIO_ID),
@ -264,7 +290,7 @@ def make_asset_list():
"goal_value": "A",
"trigger_file_path": filename,
"already_installed_file_path": "",
"patches_file_path": "",
"patches_file_path": patches_filename,
"non_invasive_recommendations_file_path": non_invasive_recommendations_filename,
"scenario_name": "Demand Reduction - no solid wall, windows, LEDs",
"multi_plan": True,
@ -283,7 +309,7 @@ def make_asset_list():
"goal_value": "A",
"trigger_file_path": filename,
"already_installed_file_path": "",
"patches_file_path": "",
"patches_file_path": patches_filename,
"non_invasive_recommendations_file_path": non_invasive_recommendations_filename,
"scenario_name": "Demand Reduction - no solid wall, floors or heating",
"multi_plan": True,
@ -294,6 +320,25 @@ def make_asset_list():
}
print(body2)
# 2.5 - full fabric, no decant
body2_5 = {
"portfolio_id": str(PORTFOLIO_ID),
"housing_type": "Private",
"goal": "Increasing EPC",
"goal_value": "A",
"trigger_file_path": filename,
"already_installed_file_path": "",
"patches_file_path": patches_filename,
"non_invasive_recommendations_file_path": non_invasive_recommendations_filename,
"scenario_name": "Demand Reduction - no solid wall, floors or heating",
"multi_plan": True,
"exclusions": [
"internal_wall_insulation", "floor_insulation", "heating", "solar_pv",
],
"budget": None,
}
print(body2_5)
# Scenario B
body3 = {
"portfolio_id": str(PORTFOLIO_ID),
@ -302,7 +347,7 @@ def make_asset_list():
"goal_value": "A",
"trigger_file_path": filename,
"already_installed_file_path": "",
"patches_file_path": "",
"patches_file_path": patches_filename,
"non_invasive_recommendations_file_path": non_invasive_recommendations_filename,
"scenario_name": "Demand Reduction, Heating Systems, Solar PV - no solid wall or floors",
"multi_plan": True,
@ -319,7 +364,7 @@ def make_asset_list():
"goal_value": "A",
"trigger_file_path": filename,
"already_installed_file_path": "",
"patches_file_path": "",
"patches_file_path": patches_filename,
"non_invasive_recommendations_file_path": non_invasive_recommendations_filename,
"scenario_name": "Whole House",
"multi_plan": True,

View file

@ -43,6 +43,9 @@ DESCRIPTIONS_TO_FUEL_TYPES = {
"Electric storage heaters, Electric storage heaters": {"fuel": "Electricity", "cop": 1},
"Boiler and radiators, electric": {"fuel": "Electricity", "cop": 0.9},
"Gas boiler/circulator, no cylinder thermostat": {"fuel": "Natural Gas", "cop": 0.9},
"Boiler and radiators, dual fuel (mineral and wood)": {"fuel": "Wood Logs", "cop": 0.9},
"Electric immersion, standard tariff, plus solar": {"fuel": "Electricity + Solar Thermal", "cop": 1},
"From main system, flue gas heat recovery": {"fuel": "Natural Gas", "cop": 0.9},
}
STARTING_DUMMY_ID_VALUE = -9999