mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
added patch to built for form newhaven
This commit is contained in:
parent
1e16babab3
commit
7e973d7955
6 changed files with 86 additions and 22 deletions
|
|
@ -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"]]
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ class PlanTriggerRequest(BaseModel):
|
|||
"air_source_heat_pump",
|
||||
"internal_wall_insulation",
|
||||
"external_wall_insulation",
|
||||
"secondary_heating"
|
||||
}
|
||||
|
||||
_allowed_goals = {"Increasing EPC"}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue